Introduce Serializer::collect_seq
This function serializes the given iterator as a sequence. Its iter parameter has type I: IntoIterator, <I as IntoIterator>::Item: Serialize, which means it will work both for iterators passed by value, therefore consuming them, and as the value for a #[serde(serialize_with)] attribute, where it will be called as Serializer::collect_seq(&self.field, serializer), relying on the common practice of implementing IntoIterator for &C where C is a data type representing some kind of collection.
This commit is contained in:
parent
ce230adf12
commit
d00a895902
@ -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<Self::SerializeStructVariant, Self::Error>;
|
||||
|
||||
/// 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<I>(self, iter: I) -> Result<Self::Ok, Self::Error>
|
||||
where I: IntoIterator,
|
||||
<I as 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<I>(iter: I) -> Iterator<I>
|
||||
data: RefCell::new(Some(iter)),
|
||||
}
|
||||
}
|
||||
|
||||
fn iterator_len_hint<I: Iterator>(iter: &I) -> Option<usize> {
|
||||
match iter.size_hint() {
|
||||
(lo, Some(hi)) if lo == hi => Some(lo),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user