diff --git a/serde_macros/src/lib.rs b/serde_macros/src/lib.rs index 4c6a09a2..23765672 100644 --- a/serde_macros/src/lib.rs +++ b/serde_macros/src/lib.rs @@ -265,9 +265,8 @@ fn serialize_tuple_struct( } #[inline] - fn size_hint(&self) -> (usize, Option) { - let size = $len - (self.state as usize); - (size, Some(size)) + fn len(&self) -> Option { + Some($len) } } @@ -349,9 +348,8 @@ fn serialize_struct( } #[inline] - fn size_hint(&self) -> (usize, Option) { - let size = $len - (self.state as usize); - (size, Some(size)) + fn len(&self) -> Option { + Some($len) } } @@ -550,8 +548,8 @@ fn serialize_variant( ast::MethodImplItem( quote_method!(cx, - fn size_hint(&self) -> (usize, Option) { - ($len - self.state as usize, Some($len - self.state as usize)) + fn len(&self) -> Option { + Some($len) } ) ), diff --git a/src/json/value.rs b/src/json/value.rs index aae566d7..f444c754 100644 --- a/src/json/value.rs +++ b/src/json/value.rs @@ -233,11 +233,7 @@ impl ser::Serializer for Serializer { fn visit_seq(&mut self, mut visitor: V) -> Result<(), ()> where V: ser::SeqVisitor, { - let len = match visitor.size_hint() { - (_, Some(len)) => len, - (len, None) => len, - }; - + let len = visitor.len().unwrap_or(0); let values = Vec::with_capacity(len); self.state.push(State::Array(values)); diff --git a/src/ser.rs b/src/ser.rs index 6eebba68..c6574649 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -163,9 +163,10 @@ pub trait SeqVisitor { fn visit(&mut self, serializer: &mut S) -> Result, S::Error> where S: Serializer; + /// Return the length of the sequence if known. #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) + fn len(&self) -> Option { + None } } @@ -173,9 +174,10 @@ pub trait MapVisitor { fn visit(&mut self, serializer: &mut S) -> Result, S::Error> where S: Serializer; + /// Return the length of the map if known. #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) + fn len(&self) -> Option { + None } } @@ -247,6 +249,7 @@ impl Serialize for Option where T: Serialize { pub struct SeqIteratorVisitor { iter: Iter, + len: Option, first: bool, } @@ -254,9 +257,10 @@ impl SeqIteratorVisitor where Iter: Iterator { #[inline] - pub fn new(iter: Iter) -> SeqIteratorVisitor { + pub fn new(iter: Iter, len: Option) -> SeqIteratorVisitor { SeqIteratorVisitor { iter: iter, + len: len, first: true, } } @@ -283,8 +287,8 @@ impl SeqVisitor for SeqIteratorVisitor } #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn len(&self) -> Option { + self.len } } @@ -297,7 +301,7 @@ impl<'a, T> Serialize for &'a [T] fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - serializer.visit_seq(SeqIteratorVisitor::new(self.iter())) + serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) } } @@ -310,12 +314,14 @@ impl Serialize for Vec where T: Serialize { } } -impl Serialize for BTreeSet where T: Serialize { +impl Serialize for BTreeSet + where T: Serialize + Ord, +{ #[inline] fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - serializer.visit_seq(SeqIteratorVisitor::new(self.iter())) + serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) } } @@ -327,7 +333,7 @@ impl Serialize for HashSet fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - serializer.visit_seq(SeqIteratorVisitor::new(self.iter())) + serializer.visit_seq(SeqIteratorVisitor::new(self.iter(), Some(self.len()))) } } @@ -394,8 +400,8 @@ macro_rules! tuple_impls { } } - fn size_hint(&self) -> (usize, Option) { - ($len, Some($len)) + fn len(&self) -> Option { + Some($len) } } @@ -520,6 +526,7 @@ tuple_impls! { pub struct MapIteratorVisitor { iter: Iter, + len: Option, first: bool, } @@ -527,9 +534,10 @@ impl MapIteratorVisitor where Iter: Iterator { #[inline] - pub fn new(iter: Iter) -> MapIteratorVisitor { + pub fn new(iter: Iter, len: Option) -> MapIteratorVisitor { MapIteratorVisitor { iter: iter, + len: len, first: true, } } @@ -557,8 +565,8 @@ impl MapVisitor for MapIteratorVisitor } #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() + fn len(&self) -> Option { + self.len } } @@ -572,7 +580,7 @@ impl Serialize for BTreeMap fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - serializer.visit_map(MapIteratorVisitor::new(self.iter())) + serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len()))) } } @@ -585,7 +593,7 @@ impl Serialize for HashMap fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - serializer.visit_map(MapIteratorVisitor::new(self.iter())) + serializer.visit_map(MapIteratorVisitor::new(self.iter(), Some(self.len()))) } } diff --git a/tests/test_ser.rs b/tests/test_ser.rs index b7d86af9..9e5ea9ba 100644 --- a/tests/test_ser.rs +++ b/tests/test_ser.rs @@ -33,15 +33,15 @@ pub enum Token<'a> { NamedUnit(&'a str), EnumUnit(&'a str, &'a str), - SeqStart(usize), - NamedSeqStart(&'a str, usize), - EnumSeqStart(&'a str, &'a str, usize), + SeqStart(Option), + NamedSeqStart(&'a str, Option), + EnumSeqStart(&'a str, &'a str, Option), SeqSep(bool), SeqEnd, - MapStart(usize), - NamedMapStart(&'a str, usize), - EnumMapStart(&'a str, &'a str, usize), + MapStart(Option), + NamedMapStart(&'a str, Option), + EnumMapStart(&'a str, &'a str, Option), MapSep(bool), MapEnd, } @@ -187,7 +187,7 @@ impl<'a> Serializer for AssertSerializer<'a> { fn visit_seq(&mut self, visitor: V) -> Result<(), ()> where V: SeqVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next(), Some(Token::SeqStart(len))); @@ -197,7 +197,7 @@ impl<'a> Serializer for AssertSerializer<'a> { fn visit_named_seq(&mut self, name: &str, visitor: V) -> Result<(), ()> where V: SeqVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next().unwrap(), Token::NamedSeqStart(name, len)); @@ -210,7 +210,7 @@ impl<'a> Serializer for AssertSerializer<'a> { visitor: V) -> Result<(), ()> where V: SeqVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next().unwrap(), Token::EnumSeqStart(name, variant, len)); @@ -227,7 +227,7 @@ impl<'a> Serializer for AssertSerializer<'a> { fn visit_map(&mut self, visitor: V) -> Result<(), ()> where V: MapVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next(), Some(Token::MapStart(len))); @@ -237,7 +237,7 @@ impl<'a> Serializer for AssertSerializer<'a> { fn visit_named_map(&mut self, name: &str, visitor: V) -> Result<(), ()> where V: MapVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next().unwrap(), Token::NamedMapStart(name, len)); @@ -250,7 +250,7 @@ impl<'a> Serializer for AssertSerializer<'a> { visitor: V) -> Result<(), ()> where V: MapVisitor { - let (len, _) = visitor.size_hint(); + let len = visitor.len(); assert_eq!(self.iter.next().unwrap(), Token::EnumMapStart(name, variant, len)); @@ -370,11 +370,11 @@ declare_tests! { } test_slice { &[0][..0] => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], &[1, 2, 3][..] => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep(true), Token::I32(1), @@ -388,23 +388,23 @@ declare_tests! { } test_vec { Vec::::new() => vec![ - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, ], vec![vec![], vec![1], vec![2, 3]] => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep(true), - Token::SeqStart(0), + Token::SeqStart(Some(0)), Token::SeqEnd, Token::SeqSep(false), - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep(true), Token::I32(1), Token::SeqEnd, Token::SeqSep(false), - Token::SeqStart(2), + Token::SeqStart(Some(2)), Token::SeqSep(true), Token::I32(2), @@ -416,13 +416,13 @@ declare_tests! { } test_tuple { (1,) => vec![ - Token::SeqStart(1), + Token::SeqStart(Some(1)), Token::SeqSep(true), Token::I32(1), Token::SeqEnd, ], (1, 2, 3) => vec![ - Token::SeqStart(3), + Token::SeqStart(Some(3)), Token::SeqSep(true), Token::I32(1), @@ -436,14 +436,14 @@ declare_tests! { } test_btreemap { btreemap![1 => 2] => vec![ - Token::MapStart(1), + Token::MapStart(Some(1)), Token::MapSep(true), Token::I32(1), Token::I32(2), Token::MapEnd, ], btreemap![1 => 2, 3 => 4] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep(true), Token::I32(1), Token::I32(2), @@ -454,15 +454,15 @@ declare_tests! { Token::MapEnd, ], btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![ - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep(true), Token::I32(1), - Token::MapStart(0), + Token::MapStart(Some(0)), Token::MapEnd, Token::MapSep(false), Token::I32(2), - Token::MapStart(2), + Token::MapStart(Some(2)), Token::MapSep(true), Token::I32(3), Token::I32(4), @@ -479,7 +479,7 @@ declare_tests! { } test_named_seq { NamedSeq(1, 2, 3) => vec![ - Token::NamedSeqStart("NamedSeq", 3), + Token::NamedSeqStart("NamedSeq", Some(3)), Token::SeqSep(true), Token::I32(1), @@ -493,7 +493,7 @@ declare_tests! { } test_named_map { NamedMap { a: 1, b: 2, c: 3 } => vec![ - Token::NamedMapStart("NamedMap", 3), + Token::NamedMapStart("NamedMap", Some(3)), Token::MapSep(true), Token::Str("a"), Token::I32(1), @@ -511,7 +511,7 @@ declare_tests! { test_enum { Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")], Enum::Seq(1, 2) => vec![ - Token::EnumSeqStart("Enum", "Seq", 2), + Token::EnumSeqStart("Enum", "Seq", Some(2)), Token::SeqSep(true), Token::I32(1), @@ -520,7 +520,7 @@ declare_tests! { Token::SeqEnd, ], Enum::Map { a: 1, b: 2 } => vec![ - Token::EnumMapStart("Enum", "Map", 2), + Token::EnumMapStart("Enum", "Map", Some(2)), Token::MapSep(true), Token::Str("a"), Token::I32(1),