From aa30ef827c8ab032c25ebed8d796d9201a90dd5b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 5 Apr 2017 15:20:14 -0700 Subject: [PATCH] Move Bytes and ByteBuf to their own crate Moved to https://github.com/serde-rs/bytes. --- serde/src/bytes.rs | 315 --------------------------------- serde/src/de/value.rs | 82 --------- serde/src/lib.rs | 1 - test_suite/tests/test_bytes.rs | 52 ------ 4 files changed, 450 deletions(-) delete mode 100644 serde/src/bytes.rs delete mode 100644 test_suite/tests/test_bytes.rs diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs deleted file mode 100644 index b6b6d02a..00000000 --- a/serde/src/bytes.rs +++ /dev/null @@ -1,315 +0,0 @@ -//! Wrapper types to enable optimized handling of `&[u8]` and `Vec`. -//! -//! Without specialization, Rust forces us to treat `&[u8]` just like any other -//! slice and `Vec` just like any other vector. In reality this particular -//! slice and vector can often be serialized and deserialized in a more -//! efficient, compact representation in many formats. -//! -//! When working with such a format, you can opt into specialized handling of -//! `&[u8]` by wrapping it in `bytes::Bytes` and `Vec` by wrapping it in -//! `bytes::ByteBuf`. -//! -//! Rust support for specialization is being tracked in -//! [rust-lang/rust#31844][specialization]. Once it lands in the stable compiler -//! we will be deprecating these wrapper types in favor of optimizing `&[u8]` -//! and `Vec` out of the box. -//! -//! [specialization]: https://github.com/rust-lang/rust/issues/31844 - -use core::{ops, fmt, char, iter, slice}; -use core::fmt::Write; - -use ser; - -#[cfg(any(feature = "std", feature = "collections"))] -pub use self::bytebuf::ByteBuf; - -#[cfg(any(feature = "std", feature = "collections"))] -#[doc(hidden)] // does anybody need this? -pub use self::bytebuf::ByteBufVisitor; - -#[cfg(feature = "collections")] -use collections::Vec; - -/////////////////////////////////////////////////////////////////////////////// - -/// Wraps a `&[u8]` in order to serialize in an efficient way. Does not support -/// deserialization. -/// -/// ```rust -/// # #[macro_use] extern crate serde_derive; -/// # extern crate serde; -/// # use std::net::IpAddr; -/// # -/// use serde::bytes::Bytes; -/// -/// # #[allow(dead_code)] -/// #[derive(Serialize)] -/// struct Packet<'a> { -/// destination: IpAddr, -/// payload: Bytes<'a>, -/// } -/// # -/// # fn main() {} -/// ``` -#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)] -pub struct Bytes<'a> { - bytes: &'a [u8], -} - -impl<'a> Bytes<'a> { - /// Wrap an existing `&[u8]`. - pub fn new(bytes: &'a [u8]) -> Self { - Bytes { bytes: bytes } - } -} - -impl<'a> fmt::Debug for Bytes<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(f.write_str("b\"")); - for c in escape_bytestring(self.bytes) { - try!(f.write_char(c)); - } - f.write_char('"') - } -} - -impl<'a> From<&'a [u8]> for Bytes<'a> { - fn from(bytes: &'a [u8]) -> Self { - Bytes::new(bytes) - } -} - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'a> From<&'a Vec> for Bytes<'a> { - fn from(bytes: &'a Vec) -> Self { - Bytes::new(bytes) - } -} - -impl<'a> Into<&'a [u8]> for Bytes<'a> { - fn into(self) -> &'a [u8] { - self.bytes - } -} - -impl<'a> ops::Deref for Bytes<'a> { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - self.bytes - } -} - -impl<'a> ser::Serialize for Bytes<'a> { - #[inline] - fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer - { - serializer.serialize_bytes(self.bytes) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[cfg(any(feature = "std", feature = "collections"))] -mod bytebuf { - use core::cmp; - use core::ops; - use core::fmt; - use core::fmt::Write; - - use ser; - use de; - - #[cfg(feature = "collections")] - use collections::{String, Vec}; - - /// Wraps a `Vec` in order to serialize and deserialize in an efficient - /// way. - /// - /// ```rust - /// # #[macro_use] extern crate serde_derive; - /// # extern crate serde; - /// # use std::net::IpAddr; - /// # - /// use serde::bytes::ByteBuf; - /// - /// # #[allow(dead_code)] - /// #[derive(Serialize, Deserialize)] - /// struct Packet { - /// destination: IpAddr, - /// payload: ByteBuf, - /// } - /// # - /// # fn main() {} - /// ``` - #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)] - pub struct ByteBuf { - bytes: Vec, - } - - impl ByteBuf { - /// Construct a new, empty `ByteBuf`. - pub fn new() -> Self { - ByteBuf::from(Vec::new()) - } - - /// Construct a new, empty `ByteBuf` with the specified capacity. - pub fn with_capacity(cap: usize) -> Self { - ByteBuf::from(Vec::with_capacity(cap)) - } - - /// Wrap existing bytes in a `ByteBuf`. - pub fn from>>(bytes: T) -> Self { - ByteBuf { bytes: bytes.into() } - } - } - - impl fmt::Debug for ByteBuf { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - try!(f.write_str("b\"")); - for c in super::escape_bytestring(self.bytes.as_ref()) { - try!(f.write_char(c)); - } - f.write_char('"') - } - } - - impl Into> for ByteBuf { - fn into(self) -> Vec { - self.bytes - } - } - - impl From> for ByteBuf { - fn from(bytes: Vec) -> Self { - ByteBuf::from(bytes) - } - } - - impl AsRef> for ByteBuf { - fn as_ref(&self) -> &Vec { - &self.bytes - } - } - - impl AsRef<[u8]> for ByteBuf { - fn as_ref(&self) -> &[u8] { - &self.bytes - } - } - - impl AsMut> for ByteBuf { - fn as_mut(&mut self) -> &mut Vec { - &mut self.bytes - } - } - - impl AsMut<[u8]> for ByteBuf { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.bytes - } - } - - impl ops::Deref for ByteBuf { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.bytes[..] - } - } - - impl ops::DerefMut for ByteBuf { - fn deref_mut(&mut self) -> &mut [u8] { - &mut self.bytes[..] - } - } - - impl ser::Serialize for ByteBuf { - fn serialize(&self, serializer: S) -> Result - where S: ser::Serializer - { - serializer.serialize_bytes(self) - } - } - - /// This type implements the `serde::de::Visitor` trait for a `ByteBuf`. - pub struct ByteBufVisitor; - - impl<'de> de::Visitor<'de> for ByteBufVisitor { - type Value = ByteBuf; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("byte array") - } - - #[inline] - fn visit_unit(self) -> Result - where E: de::Error - { - Ok(ByteBuf::new()) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where V: de::SeqVisitor<'de> - { - 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); - } - - Ok(ByteBuf::from(values)) - } - - #[inline] - fn visit_bytes(self, v: &[u8]) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - #[inline] - fn visit_byte_buf(self, v: Vec) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - fn visit_str(self, v: &str) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - - fn visit_string(self, v: String) -> Result - where E: de::Error - { - Ok(ByteBuf::from(v)) - } - } - - impl<'de> de::Deserialize<'de> for ByteBuf { - #[inline] - fn deserialize(deserializer: D) -> Result - where D: de::Deserializer<'de> - { - deserializer.deserialize_byte_buf(ByteBufVisitor) - } - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[inline] -fn escape_bytestring<'a> - (bytes: &'a [u8]) - -> iter::FlatMap, char::EscapeDefault, fn(&u8) -> char::EscapeDefault> { - fn f(b: &u8) -> char::EscapeDefault { - char::from_u32(*b as u32).unwrap().escape_default() - } - bytes.iter().flat_map(f as fn(&u8) -> char::EscapeDefault) -} diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index 13aaaba7..f4d1eba0 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -29,7 +29,6 @@ use core::iter::{self, Iterator}; use core::marker::PhantomData; use de::{self, Expected, SeqVisitor}; -use bytes; /////////////////////////////////////////////////////////////////////////////// @@ -959,87 +958,6 @@ impl<'de, V_> de::Deserializer<'de> for MapVisitorDeserializer /////////////////////////////////////////////////////////////////////////////// -impl<'de, 'a, E> ValueDeserializer<'de, E> for bytes::Bytes<'a> - where E: de::Error -{ - type Deserializer = BytesDeserializer<'a, E>; - - fn into_deserializer(self) -> BytesDeserializer<'a, E> { - BytesDeserializer { - value: self.into(), - marker: PhantomData, - } - } -} - -/// A helper deserializer that deserializes a `&[u8]`. -pub struct BytesDeserializer<'a, E> { - value: &'a [u8], - marker: PhantomData, -} - -impl<'de, 'a, E> de::Deserializer<'de> for BytesDeserializer<'a, E> - where E: de::Error -{ - type Error = E; - - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_bytes(self.value) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'de, E> ValueDeserializer<'de, E> for bytes::ByteBuf - where E: de::Error -{ - type Deserializer = ByteBufDeserializer; - - fn into_deserializer(self) -> Self::Deserializer { - ByteBufDeserializer { - value: self.into(), - marker: PhantomData, - } - } -} - -/// A helper deserializer that deserializes a `Vec`. -#[cfg(any(feature = "std", feature = "collections"))] -pub struct ByteBufDeserializer { - value: Vec, - marker: PhantomData, -} - -#[cfg(any(feature = "std", feature = "collections"))] -impl<'de, E> de::Deserializer<'de> for ByteBufDeserializer - where E: de::Error -{ - type Error = E; - - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - visitor.visit_byte_buf(self.value) - } - - forward_to_deserialize! { - bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option - seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct - struct struct_field tuple enum ignored_any byte_buf - } -} - -/////////////////////////////////////////////////////////////////////////////// - mod private { use de::{self, Unexpected}; use core::marker::PhantomData; diff --git a/serde/src/lib.rs b/serde/src/lib.rs index cfd2f7d0..eb7aa326 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -93,7 +93,6 @@ pub use de::{Deserialize, Deserializer}; #[macro_use] mod macros; -pub mod bytes; pub mod de; #[cfg(feature = "std")] #[doc(hidden)] diff --git a/test_suite/tests/test_bytes.rs b/test_suite/tests/test_bytes.rs deleted file mode 100644 index 4da64e1c..00000000 --- a/test_suite/tests/test_bytes.rs +++ /dev/null @@ -1,52 +0,0 @@ -extern crate serde; -use serde::bytes::{ByteBuf, Bytes}; - -extern crate serde_test; -use serde_test::{assert_tokens, assert_ser_tokens, assert_de_tokens, Token}; - -#[test] -fn test_bytes() { - let empty = Bytes::new(&[]); - assert_ser_tokens(&empty, &[Token::Bytes(b"")]); - - let buf = vec![65, 66, 67]; - let bytes = Bytes::new(&buf); - assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]); -} - -#[test] -fn test_byte_buf() { - let empty = ByteBuf::new(); - assert_tokens(&empty, &[Token::Bytes(b"")]); - assert_de_tokens(&empty, &[Token::ByteBuf(b"")]); - assert_de_tokens(&empty, &[Token::Str("")]); - assert_de_tokens(&empty, &[Token::String("")]); - assert_de_tokens(&empty, &[ - Token::Seq(None), - Token::SeqEnd, - ]); - assert_de_tokens(&empty, &[ - Token::Seq(Some(0)), - Token::SeqEnd, - ]); - - let buf = ByteBuf::from(vec![65, 66, 67]); - assert_tokens(&buf, &[Token::Bytes(b"ABC")]); - assert_de_tokens(&buf, &[Token::ByteBuf(b"ABC")]); - assert_de_tokens(&buf, &[Token::Str("ABC")]); - assert_de_tokens(&buf, &[Token::String("ABC")]); - assert_de_tokens(&buf, &[ - Token::Seq(None), - Token::U8(65), - Token::U8(66), - Token::U8(67), - Token::SeqEnd, - ]); - assert_de_tokens(&buf, &[ - Token::Seq(Some(3)), - Token::U8(65), - Token::U8(66), - Token::U8(67), - Token::SeqEnd, - ]); -}