diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index c4db5b1f..ad36b60b 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -825,16 +825,6 @@ seq_impl!( HashSet::reserve, HashSet::insert); -#[cfg(any(feature = "std", feature = "alloc"))] -seq_impl!( - Vec, - seq, - Vec::clear, - Vec::with_capacity(size_hint::cautious(seq.size_hint())), - Vec::reserve, - Vec::push -); - #[cfg(any(feature = "std", feature = "alloc"))] seq_impl!( VecDeque, @@ -847,6 +837,97 @@ seq_impl!( //////////////////////////////////////////////////////////////////////////////// +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de, T> Deserialize<'de> for Vec +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct VecVisitor { + marker: PhantomData, + } + + impl<'de, T> Visitor<'de> for VecVisitor + where + T: Deserialize<'de>, + { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let mut values = Vec::with_capacity(size_hint::cautious(seq.size_hint())); + + while let Some(value) = try!(seq.next_element()) { + values.push(value); + } + + Ok(values) + } + } + + let visitor = VecVisitor { marker: PhantomData }; + deserializer.deserialize_seq(visitor) + } + + fn deserialize_in_place(deserializer: D, place: &mut Self) -> Result<(), D::Error> + where + D: Deserializer<'de>, + { + struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec); + + impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T> + where + T: Deserialize<'de>, + { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a sequence") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + let hint = size_hint::cautious(seq.size_hint()); + if let Some(additional) = hint.checked_sub(self.0.len()) { + self.0.reserve(additional); + } + + for i in 0..self.0.len() { + let next = { + let next_place = InPlaceSeed(&mut self.0[i]); + try!(seq.next_element_seed(next_place)) + }; + if next.is_none() { + self.0.truncate(i); + return Ok(()); + } + } + + while let Some(value) = try!(seq.next_element()) { + self.0.push(value); + } + + Ok(()) + } + } + + deserializer.deserialize_seq(VecInPlaceVisitor(place)) + } +} + +//////////////////////////////////////////////////////////////////////////////// + struct ArrayVisitor { marker: PhantomData, }