How to serialize an Iterator to JSON?

I've got a large list of serializable items, but I'm only given an iterator over them.
Is there a way to serialize them into Json with serde?

The only working way I've found is first collecting the items into a vector first:

pub fn write_as_json<'a, I, P>(&mut self, groups: I) -> io::Result<()>
    where
        I: Iterator<Item = &'a FileGroup<P>>,
        P: Serialize + 'a,
{
        let groups: Vec<&FileGroup<P>> = groups.collect();
        serde_json::to_writer_pretty(&mut self.out, &groups)?
}

Unfortunately, I can't pass an iterator to to_writer_pretty directly, because it expects a non-mutable reference:

pub fn write_as_json<'a, I, P>(&mut self, groups: I) -> io::Result<()>
    where
        I: Iterator<Item = &'a FileGroup<P>>,
        P: Serialize + 'a,
{
        serde_json::to_writer_pretty(&mut self.out, groups)?  // expected &T but got I instead
}

The easiest thing I can think of is .collect()ing the items in the Iterator to eg a Vec<T> and serializing that.

And since that's what you've been doing, I'd say it's fine.

1 Like

You can make an wrapper type over the iterator and impl Serialize on it.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e82b44a14dff05fb3ef6964b8667b79a

6 Likes

Just to point out a small thing, IntoIterator is more general than Iterator since any Iterator implements IntoIterator for itself.

2 Likes

Thank you. I used the wrapper solution.