devela/data/serde/utils/
sequence_wrapper.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// devela::data::serde::utils::sequence_wrapper
//
//!
//
// THINK
// - maybe there's a simpler way
// - what happens with CAP? if it has to coincide... then why can't I reinvent?
// - what happens with Storage? should it be ... chosen when deserialized?

#[cfg(feature = "dep_serde")]
#[allow(unused_imports)]
pub use dep_serde::*;

// https://serde.rs/impl-serialize.html
// https://serde.rs/impl-deserialize.html
#[cfg(feature = "dep_serde")]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "dep_serde")))]
mod dep_serde {
    use serde::ser::{Serialize, SerializeSeq, Serializer};

    #[doc = crate::TAG_ITERATOR!()]
    /// A helper struct to serialize an iterator as a sequence.
    ///
    /// This struct wraps an iterator and provides an implementation of
    /// [`Serialize`] to serialize its elements as a sequence.
    pub struct SerializeSequence<I>(I);

    impl<I> From<I> for SerializeSequence<I> {
        /// Constructs a `SerializeSequence` from an iterator.
        fn from(iter: I) -> Self {
            Self(iter)
        }
    }

    impl<I, T> Serialize for SerializeSequence<I>
    where
        I: Clone + Iterator<Item = T>,
        T: Serialize,
    {
        fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
            // If the iterator has an exact size, use its length; otherwise, fall back to None.
            let length = self.0.clone().size_hint().0;
            let mut seq = serializer.serialize_seq((length > 0).then_some(length))?;
            for element in self.0.clone() {
                seq.serialize_element(&element)?;
            }
            seq.end()
        }
    }
}