From ebe214e8ac127e7e7c2f7cbbf1cfaa7cb848772f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 15:19:29 -0700 Subject: [PATCH] Remove CString dependency on ByteBuf --- serde/src/de/impls.rs | 67 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9f666729..5d5e8e8e 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -58,9 +58,6 @@ use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, VariantVisitor, Visitor}; use de::from_primitive::FromPrimitive; -#[cfg(feature = "std")] -use bytes::ByteBuf; - /////////////////////////////////////////////////////////////////////////////// struct UnitVisitor; @@ -354,13 +351,52 @@ impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { /////////////////////////////////////////////////////////////////////////////// -#[cfg(all(feature = "std", feature="unstable"))] -impl<'de> Deserialize<'de> for Box { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> +#[cfg(feature = "std")] +struct CStringVisitor; + +#[cfg(feature = "std")] +impl<'de> Visitor<'de> for CStringVisitor { + type Value = CString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq(self, mut visitor: V) -> Result + where V: SeqVisitor<'de> { - let s = try!(CString::deserialize(deserializer)); - Ok(s.into_boxed_c_str()) + let len = cmp::min(visitor.size_hint().0, 4096); + let mut values = Vec::with_capacity(len); + + while let Some(value) = try!(visitor.visit()) { + values.push(value); + } + + CString::new(values).map_err(Error::custom) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_str(self, v: &str) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) + } + + fn visit_string(self, v: String) -> Result + where E: Error + { + CString::new(v).map_err(Error::custom) } } @@ -369,8 +405,17 @@ impl<'de> Deserialize<'de> for CString { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de> { - let bytes = try!(ByteBuf::deserialize(deserializer)); - CString::new(bytes).map_err(Error::custom) + deserializer.deserialize_byte_buf(CStringVisitor) + } +} + +#[cfg(all(feature = "std", feature="unstable"))] +impl<'de> Deserialize<'de> for Box { + fn deserialize(deserializer: D) -> Result + where D: Deserializer<'de> + { + let s = try!(CString::deserialize(deserializer)); + Ok(s.into_boxed_c_str()) } }