diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 42ccd169..9fa5ca32 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -102,6 +102,7 @@ use error; use core::cell::RefCell; use core::fmt::Display; +use core::iter::IntoIterator; mod impls; mod impossible; @@ -242,7 +243,7 @@ pub trait Serialize { /// is the `serde_json::value::Serializer` (distinct from the main `serde_json` /// serializer) that produces a `serde_json::Value` data structure in memory as /// output. -pub trait Serializer { +pub trait Serializer: Sized { /// The output type produced by this `Serializer` during successful /// serialization. Most serializers that produce text or binary output /// should set `Ok = ()` and serialize into an `io::Write` or buffer @@ -607,6 +608,23 @@ pub trait Serializer { variant: &'static str, len: usize, ) -> Result; + + /// Collect an iterator as a sequence. + /// + /// The default implementation serializes each item yielded by the iterator + /// using `Self::SerializeSeq`. Implementors should not need to override + /// this method. + fn collect_seq(self, iter: I) -> Result + where I: IntoIterator, + ::Item: Serialize, + { + let iter = iter.into_iter(); + let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); + for item in iter { + try!(serializer.serialize_element(&item)); + } + serializer.end() + } } /// Returned from `Serializer::serialize_seq` and @@ -826,3 +844,10 @@ pub fn iterator(iter: I) -> Iterator data: RefCell::new(Some(iter)), } } + +fn iterator_len_hint(iter: &I) -> Option { + match iter.size_hint() { + (lo, Some(hi)) if lo == hi => Some(lo), + _ => None, + } +}