Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render from borrowed events? #24

Closed
kaj opened this issue Mar 16, 2023 · 3 comments
Closed

Render from borrowed events? #24

kaj opened this issue Mar 16, 2023 · 3 comments

Comments

@kaj
Copy link

kaj commented Mar 16, 2023

Hi! The jotdown format and this crate seems awesome, thanks!

I'd like to be able to create multiple html outputs from the same jotdown file, by finding different parts of the event stream and rendering them separately. Something like this:

let jd = jotdown::Parser::new(&read_to_string(path)?).collect::<Vec<_>>();

let part_a: &[&Event] = some_filter(&jd);
let html_a = String::new();
jotdown::html::push(part_a.iter(), &mut html_a);

let part_b: &[&Event] = other_filter(&jd);
let html_b = String::new();
jotdown::html::push(part_b.iter(), &mut html_b);

This fails because iterating a slice can only give an iterator of borrowed events, not owned events.

It could be fixed by using part_a.iter().cloned(), but Event currently don't implement Clone. But I don't really see a reason that formatting html should require ownership of the events, so I think it should be relatively easy to add formatting of borrowed events.

If there is agreement that this would be useful, I'm open for attempting to write a PR implementing it.

@hellux
Copy link
Owner

hellux commented Mar 16, 2023 via email

@kaj
Copy link
Author

kaj commented Mar 17, 2023

Thanks, cloning works fine for me (at least for now). I might attempt to make a make it possible to use references directly later, I think it should be possible to take an impl Iterator<item=impl AsRef<Event>> or something similar, but now that Render is a trait, that might be more complicated, at least until rust support for generics in traits have improved ...

Feel free to tag this issue for handling later, or just closing it as you see fit.

@hellux
Copy link
Owner

hellux commented Mar 17, 2023

I did some experimentation on a branch, render_ref. The trait then looks like this:

pub trait Render {
    fn render_event<'s, W: fmt::Write>(&mut self, e: &Event<'s>, out: W) -> std::fmt::Result;
    fn render_epilogue<W: fmt::Write>(&mut self, out: W) -> std::fmt::Result;

    fn push<'s, I, W>(&mut self, mut events: I, mut out: W) -> fmt::Result
    where
        I: Iterator<Item = Event<'s>>,
        W: fmt::Write,
    {
        events.try_for_each(|e| self.render_event(&e, &mut out))?;
        self.render_epilogue(&mut out)
    }

    fn push_ref<'s, E, I, W>(&mut self, mut events: I, mut out: W) -> fmt::Result
    where
        E: AsRef<Event<'s>>,
        I: Iterator<Item = E>,
        W: fmt::Write,
    {
        events.try_for_each(|e| self.render_event(e.as_ref(), &mut out))?;
        self.render_epilogue(&mut out)
    }

    fn write<'s, I, W>(&mut self, events: I, out: W) -> io::Result<()>
    where
        I: Iterator<Item = Event<'s>>,
        W: io::Write,
    { .. }

    fn write_ref<'s, E, I, W>(&mut self, events: I, out: W) -> io::Result<()>
    where
        E: AsRef<Event<'s>>,
        I: Iterator<Item = E>,
        W: io::Write,
    { .. }
}

The renderer has to render each event separately, which slightly decreases its flexibility (although, a renderer could choose to implement push/push_ref manually also). There is a slight performance decrease, not sure why. The rendering is almost 10% slower (rendering is around 10% of parse time, so in the magnitude of 1%).

Any thoughts on this API?

hellux added a commit that referenced this issue Mar 19, 2023
hellux added a commit that referenced this issue Mar 19, 2023
hellux added a commit that referenced this issue Mar 19, 2023
allow rendering of iterators with borrowed events

resolves #24
hellux added a commit that referenced this issue Mar 19, 2023
allow rendering of iterators with borrowed events

resolves #24
hellux added a commit that referenced this issue Mar 21, 2023
allow rendering of iterators with borrowed events

resolves #24
hellux added a commit that referenced this issue Mar 21, 2023
allow rendering of iterators with borrowed events

resolves #24
hellux added a commit that referenced this issue Mar 21, 2023
allow rendering of iterators with borrowed events

resolves #24
hellux added a commit that referenced this issue Mar 21, 2023
allow rendering of iterators with borrowed events

resolves #24
@hellux hellux closed this as completed in f186ca9 Mar 25, 2023
hellux added a commit that referenced this issue Apr 5, 2023
allow rendering iterators with borrowed events

resolves #24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants