Serialize/Deserialize this struct

Hi all, I'm struggling to serialize a struct which contains a dynamic trait object. Is this possible? I had a google, but I don't think I understand the problems here.

#[derive(Serialize, Deserialize)]
pub struct ListStream {
    pub stream: Box<dyn Iterator<Item = Value> + Send + 'static>,
    pub ctrlc: Option<Arc<AtomicBool>>,
}

With compiler error:

impl ListStreamIteratorTrait for ListStreamIterator {}
       ^^^^^^^^^^^^^^^^^^^^^^^ the trait `config::_::_serde::Serialize` is not implemented for `(dyn Iterator<Item = value::Value> + Send + 'static)`

Thanks,
M

serde has no way of knowing how to serialize your Box<dyn Iterator> because all we know about this object is that it implements the Iterator method. That's what the compiler error is trying to tell you.

Serializing an iterator would require consuming it because iterating over it is the only way to serialize its elements, however the serialize() method only takes &self. Additionally, serde::Serialize and serde::Deserialize aren't object safe, so there's no way to create a Box<dyn Iterator + serde::Serialize + serde::Deserialize>.

You probably want the stream field to be a Vec<Value>.

3 Likes

Iterator is not a trait you own, so if it doesn't provide an implementation of serde's Serialize trait then you can't use it du to the trait bound needed by serde.

What are you trying to achieve here by using a trait object? Why are you not using an enum instead?

2 Likes

You may be trying to use iterators in their C++ meaning, where they can work as a generic description of a collection. In Rust that approach doesn't work well. Rust iterators are single-use only, and are meant to be used for loops, not for data storage.

Rust iterators are more like an in-progress database query than a collection. It wouldn't make sense to deserialize a database connection from a file, so deserializing an iterator is similarly weird.

I suggest take a step back, and try to serialize/deserialize whatever source the ListStream is iterating from. Or change ListStream to be List and hold a custom collection type (perhaps an enum if there are multiple collections possible).

5 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.