Compare commits

...

10 Commits

Author SHA1 Message Date
David Tolnay 59e48997dd Release 0.9.0-rc4 2017-01-25 10:14:43 -08:00
Oliver Schneider ffcd97834f Merge pull request #721 from serde-rs/size
Remove usize and isize from data model
2017-01-25 19:08:02 +01:00
David Tolnay e0c049dbf2 Remove usize and isize from data model 2017-01-25 09:08:06 -08:00
David Tolnay 8cb6607e82 Merge pull request #719 from serde-rs/rustdoc
Serde rustdoc
2017-01-24 20:59:26 -08:00
David Tolnay 1ffb0570b6 Do not require rustdoc tests to run on stable 2017-01-24 20:47:31 -08:00
David Tolnay 2c1dd60575 Serde rustdoc 2017-01-24 20:37:11 -08:00
David Tolnay 24f849da2d Remove unused #[macro_use]
I think this was for the quasi-quoting macros back in the day.
2017-01-24 09:28:00 -08:00
David Tolnay a5024a4238 Merge pull request #717 from serde-rs/badger
add travis badge to crates.io
2017-01-24 05:35:55 -08:00
Oliver Schneider b105423e5e add travis badge to crates.io 2017-01-24 10:30:10 +01:00
Oliver Schneider 42c1bc2907 Merge pull request #716 from serde-rs/ref
Serialize T by ref
2017-01-24 08:31:24 +01:00
24 changed files with 1284 additions and 477 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ before_script:
- export PATH=$HOME/.local/bin:$PATH - export PATH=$HOME/.local/bin:$PATH
script: script:
- (cd serde && travis-cargo build) - (cd serde && travis-cargo build)
- (cd serde && travis-cargo --skip nightly test) - (cd serde && travis-cargo --only beta test)
- (cd serde && travis-cargo --only nightly test -- --features unstable-testing) - (cd serde && travis-cargo --only nightly test -- --features unstable-testing)
- (cd serde && travis-cargo build -- --no-default-features) - (cd serde && travis-cargo build -- --no-default-features)
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc) - (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
+7 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "0.9.0-rc3" version = "0.9.0-rc4"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -12,6 +12,9 @@ keywords = ["serde", "serialization"]
categories = ["encoding"] categories = ["encoding"]
include = ["Cargo.toml", "src/**/*.rs"] include = ["Cargo.toml", "src/**/*.rs"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
[features] [features]
default = ["std"] default = ["std"]
@@ -23,3 +26,6 @@ unstable-testing = ["clippy", "unstable", "std"]
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } clippy = { version = "^0.*", optional = true }
[dev-dependencies]
serde_derive = "0.9.0-rc3"
+60 -4
View File
@@ -1,4 +1,20 @@
//! Helper module to enable serializing bytes more efficiently //! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces us to treat `&[u8]` just like any other
//! slice and `Vec<u8>` 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<u8>` 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<u8>` out of the box.
//!
//! [specialization]: https://github.com/rust-lang/rust/issues/31844
use core::{ops, fmt, char, iter, slice}; use core::{ops, fmt, char, iter, slice};
use core::fmt::Write; use core::fmt::Write;
@@ -6,14 +22,36 @@ use core::fmt::Write;
use ser; use ser;
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
pub use self::bytebuf::{ByteBuf, ByteBufVisitor}; 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")] #[cfg(feature = "collections")]
use collections::Vec; use collections::Vec;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array. /// 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)] #[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> { pub struct Bytes<'a> {
bytes: &'a [u8], bytes: &'a [u8],
@@ -86,7 +124,25 @@ mod bytebuf {
#[cfg(feature = "collections")] #[cfg(feature = "collections")]
use collections::{String, Vec}; use collections::{String, Vec};
/// `ByteBuf` wraps a `Vec<u8>` and serializes as a byte array. /// Wraps a `Vec<u8>` 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)] #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf { pub struct ByteBuf {
bytes: Vec<u8>, bytes: Vec<u8>,
+3 -5
View File
@@ -180,12 +180,10 @@ macro_rules! impl_deserialize_num {
formatter.write_str(stringify!($ty)) formatter.write_str(stringify!($ty))
} }
impl_deserialize_num_method!($ty, isize, visit_isize, from_isize, Signed, i64);
impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64); impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64);
impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64); impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64);
impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64); impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64);
impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64); impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64);
impl_deserialize_num_method!($ty, usize, visit_usize, from_usize, Unsigned, u64);
impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64); impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64);
impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64); impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64);
impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64); impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64);
@@ -209,12 +207,12 @@ macro_rules! impl_deserialize_num {
} }
} }
impl_deserialize_num!(isize, deserialize_isize); impl_deserialize_num!(isize, deserialize_i64);
impl_deserialize_num!(i8, deserialize_i8); impl_deserialize_num!(i8, deserialize_i8);
impl_deserialize_num!(i16, deserialize_i16); impl_deserialize_num!(i16, deserialize_i16);
impl_deserialize_num!(i32, deserialize_i32); impl_deserialize_num!(i32, deserialize_i32);
impl_deserialize_num!(i64, deserialize_i64); impl_deserialize_num!(i64, deserialize_i64);
impl_deserialize_num!(usize, deserialize_usize); impl_deserialize_num!(usize, deserialize_u64);
impl_deserialize_num!(u8, deserialize_u8); impl_deserialize_num!(u8, deserialize_u8);
impl_deserialize_num!(u16, deserialize_u16); impl_deserialize_num!(u16, deserialize_u16);
impl_deserialize_num!(u32, deserialize_u32); impl_deserialize_num!(u32, deserialize_u32);
@@ -1150,7 +1148,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
formatter.write_str("`Ok` or `Err`") formatter.write_str("`Ok` or `Err`")
} }
fn visit_usize<E>(self, value: usize) -> Result<Field, E> where E: Error { fn visit_u32<E>(self, value: u32) -> Result<Field, E> where E: Error {
match value { match value {
0 => Ok(Field::Ok), 0 => Ok(Field::Ok),
1 => Ok(Field::Err), 1 => Ok(Field::Err),
+497 -174
View File
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -28,10 +28,9 @@ pub fn missing_field<V, E>(field: &'static str) -> Result<V, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
string unit seq seq_fixed_size bytes byte_buf map unit_struct seq_fixed_size bytes byte_buf map unit_struct newtype_struct
newtype_struct tuple_struct struct struct_field tuple enum tuple_struct struct struct_field tuple enum ignored_any
ignored_any
} }
} }
+44 -45
View File
@@ -126,9 +126,9 @@ impl<E> de::Deserializer for UnitDeserializer<E>
type Error = E; type Error = E;
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
unit seq seq_fixed_size bytes map unit_struct newtype_struct seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct_field tuple enum ignored_any byte_buf
} }
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -147,7 +147,7 @@ impl<E> de::Deserializer for UnitDeserializer<E>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer { macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident) => { ($ty:ty, $name:ident, $method:ident $($cast:tt)*) => {
/// A helper deserializer that deserializes a number. /// A helper deserializer that deserializes a number.
pub struct $name<E>($ty, PhantomData<E>); pub struct $name<E>($ty, PhantomData<E>);
@@ -167,16 +167,15 @@ macro_rules! primitive_deserializer {
type Error = E; type Error = E;
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit
string unit option seq seq_fixed_size bytes map unit_struct option seq seq_fixed_size bytes map unit_struct newtype_struct
newtype_struct tuple_struct struct struct_field tuple enum tuple_struct struct struct_field tuple enum ignored_any byte_buf
ignored_any byte_buf
} }
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor,
{ {
visitor.$method(self.0) visitor.$method(self.0 $($cast)*)
} }
} }
} }
@@ -187,12 +186,12 @@ primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16); primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32); primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64); primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize); primitive_deserializer!(isize, IsizeDeserializer, visit_i64 as i64);
primitive_deserializer!(u8, U8Deserializer, visit_u8); primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16); primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32); primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64); primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize); primitive_deserializer!(usize, UsizeDeserializer, visit_u64 as u64);
primitive_deserializer!(f32, F32Deserializer, visit_f32); primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64); primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char); primitive_deserializer!(char, CharDeserializer, visit_char);
@@ -233,9 +232,9 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple ignored_any byte_buf struct struct_field tuple ignored_any byte_buf
} }
} }
@@ -291,9 +290,9 @@ impl<E> de::Deserializer for StringDeserializer<E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple ignored_any byte_buf struct struct_field tuple ignored_any byte_buf
} }
} }
@@ -353,9 +352,9 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple ignored_any byte_buf struct struct_field tuple ignored_any byte_buf
} }
} }
@@ -426,9 +425,9 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct struct_field tuple enum ignored_any byte_buf
} }
} }
@@ -538,9 +537,9 @@ impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct struct_field tuple enum ignored_any byte_buf
} }
} }
@@ -634,9 +633,9 @@ impl<I, E> de::Deserializer for MapDeserializer<I, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option bytes map unit_struct newtype_struct tuple_struct struct bytes map unit_struct newtype_struct tuple_struct struct struct_field
struct_field tuple enum ignored_any byte_buf tuple enum ignored_any byte_buf
} }
} }
@@ -728,9 +727,9 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
type Error = E; type Error = E;
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option bytes map unit_struct newtype_struct tuple_struct struct bytes map unit_struct newtype_struct tuple_struct struct struct_field
struct_field tuple enum ignored_any byte_buf tuple enum ignored_any byte_buf
} }
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -872,9 +871,9 @@ impl<V_, E> de::Deserializer for MapVisitorDeserializer<V_, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct struct_field tuple enum ignored_any byte_buf
} }
} }
@@ -905,9 +904,9 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct struct_field tuple enum ignored_any byte_buf
} }
} }
@@ -941,9 +940,9 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
} }
forward_to_deserialize! { forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
unit option seq seq_fixed_size bytes map unit_struct newtype_struct seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf struct struct_field tuple enum ignored_any byte_buf
} }
} }
@@ -975,16 +974,16 @@ mod private {
} }
fn visit_tuple<V>(self, fn visit_tuple<V>(self,
_len: usize, _len: usize,
_visitor: V) -> Result<V::Value, Self::Error> _visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant")) Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"))
} }
fn visit_struct<V>(self, fn visit_struct<V>(self,
_fields: &'static [&'static str], _fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error> _visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant")) Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"))
+59 -8
View File
@@ -1,13 +1,63 @@
//! Serde Serialization Framework //! # Serde
//! //!
//! Serde is a powerful framework that enables serialization libraries to generically serialize //! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! Rust data structures without the overhead of runtime type information. In many situations, the //! structures efficiently and generically.
//! handshake protocol between serializers and serializees can be completely optimized away,
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
//! type.
//! //!
//! For a detailed tutorial on the different ways to use serde please check out the //! The Serde ecosystem consists of data structures that know how to serialize
//! [github repository](https://github.com/serde-rs/serde) //! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website https://serde.rs/ for additional documentation and
//! usage examples.
//!
//! ### Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's code
//! generation to automatically derive implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform roughly the same speed as a handwritten serializer
//! for the specific selection of data structure and data format.
//!
//! ### Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON](https://github.com/serde-rs/json), the ubiquitous JavaScript Object
//! Notation used by many HTTP APIs.
//! - [Bincode](https://github.com/TyOverby/bincode), a compact binary format
//! used for IPC within the Servo rendering engine.
//! - [CBOR](https://github.com/pyfisch/cbor), a Concise Binary Object
//! Representation designed for small message size without the need for
//! version negotiation.
//! - [YAML](https://github.com/dtolnay/serde-yaml), a popular human-friendly
//! configuration language that ain't markup language.
//! - [MessagePack](https://github.com/3Hren/msgpack-rust), an efficient binary
//! format that resembles a compact JSON.
//! - [TOML](https://github.com/alexcrichton/toml-rs), a minimal configuration
//! format used by [Cargo](http://doc.crates.io/manifest.html).
//! - [Pickle](https://github.com/birkenfeld/serde-pickle), a format common in
//! the Python world.
//! - [Hjson](https://github.com/laktak/hjson-rust), a variant of JSON designed
//! to be readable and writable by humans.
//! - [BSON](https://github.com/zonyitoo/bson-rs), the data storage and network
//! transfer format used by MongoDB.
//! - [URL](https://github.com/nox/serde_urlencoded), the x-www-form-urlencoded
//! format.
//! - [XML](https://github.com/serde-rs/xml), the flexible machine-friendly W3C
//! standard. *(deserialization only)*
//! - [Envy](https://github.com/softprops/envy), a way to deserialize
//! environment variables into Rust structs. *(deserialization only)*
//! - [Redis](https://github.com/OneSignal/serde-redis), deserialize values from
//! Redis when using [redis-rs](https://crates.io/crates/redis).
//! *(deserialization only)*
#![doc(html_root_url="https://docs.serde.rs")] #![doc(html_root_url="https://docs.serde.rs")]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
@@ -45,6 +95,7 @@ mod macros;
pub mod bytes; pub mod bytes;
pub mod de; pub mod de;
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[doc(hidden)]
pub mod iter; pub mod iter;
pub mod ser; pub mod ser;
#[cfg_attr(feature = "std", doc(hidden))] #[cfg_attr(feature = "std", doc(hidden))]
+51 -15
View File
@@ -32,9 +32,6 @@ macro_rules! forward_to_deserialize_helper {
(bool) => { (bool) => {
forward_to_deserialize_method!{deserialize_bool()} forward_to_deserialize_method!{deserialize_bool()}
}; };
(usize) => {
forward_to_deserialize_method!{deserialize_usize()}
};
(u8) => { (u8) => {
forward_to_deserialize_method!{deserialize_u8()} forward_to_deserialize_method!{deserialize_u8()}
}; };
@@ -47,9 +44,6 @@ macro_rules! forward_to_deserialize_helper {
(u64) => { (u64) => {
forward_to_deserialize_method!{deserialize_u64()} forward_to_deserialize_method!{deserialize_u64()}
}; };
(isize) => {
forward_to_deserialize_method!{deserialize_isize()}
};
(i8) => { (i8) => {
forward_to_deserialize_method!{deserialize_i8()} forward_to_deserialize_method!{deserialize_i8()}
}; };
@@ -124,28 +118,70 @@ macro_rules! forward_to_deserialize_helper {
}; };
} }
/// Helper to forward `Deserializer` methods to `Deserializer::deserialize`. // Super explicit first paragraph because this shows up at the top level and
/// Every given method ignores all arguments and forwards to `deserialize`. // trips up people who are just looking for basic Serialize / Deserialize
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`; a // documentation.
/// better approach is tracked in [serde-rs/serde#521][1]. //
/// Helper macro when implementing the `Deserializer` part of a new data format
/// for Serde.
/// ///
/// ```rust,ignore /// Some `Deserializer` implementations for self-describing formats do not care
/// what hint the `Visitor` gives them, they just want to blindly call the
/// `Visitor` method corresponding to the data they can tell is in the input.
/// This requires repetitive implementations of all the `Deserializer` trait
/// methods.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// # impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// # fn deserialize<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor
/// # { unimplemented!() }
/// #
/// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// self.deserialize(visitor)
/// }
/// # forward_to_deserialize! {
/// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// # tuple_struct struct struct_field tuple enum ignored_any
/// # }
/// # }
/// # fn main() {}
/// ```
///
/// The `forward_to_deserialize!` macro implements these simple forwarding
/// methods so that they forward directly to `Deserializer::deserialize`. You
/// can choose which methods to forward.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// impl Deserializer for MyDeserializer { /// impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> /// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor /// where V: Visitor
/// { /// {
/// /* ... */ /// /* ... */
/// # let _ = visitor;
/// # unimplemented!()
/// } /// }
/// ///
/// forward_to_deserialize! { /// forward_to_deserialize! {
/// bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string /// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// unit option seq seq_fixed_size bytes map unit_struct newtype_struct /// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any /// tuple_struct struct struct_field tuple enum ignored_any
/// } /// }
/// } /// }
/// # fn main() {}
/// ``` /// ```
///
/// [1]: https://github.com/serde-rs/serde/issues/521
#[macro_export] #[macro_export]
macro_rules! forward_to_deserialize { macro_rules! forward_to_deserialize {
($($func:ident)*) => { ($($func:ident)*) => {
+5 -11
View File
@@ -1,9 +1,3 @@
//! Implementations for all of Rust's builtin types. Tuples implement the `Serialize` trait if they
//! have at most 16 fields. Arrays implement the `Serialize` trait if their length is 32 or less.
//! You can always forward array serialization to slice serialization, which works for any length.
//! Long tuples are best replaced by tuple structs, for which you can use `derive(Serialize)`. In
//! that case the number of fields is irrelevant.
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::borrow::Cow; use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "collections", not(feature = "std")))]
@@ -80,25 +74,25 @@ use super::Iterator;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit { macro_rules! impl_visit {
($ty:ty, $method:ident) => { ($ty:ty, $method:ident $($cast:tt)*) => {
impl Serialize for $ty { impl Serialize for $ty {
#[inline] #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer, where S: Serializer,
{ {
serializer.$method(*self) serializer.$method(*self $($cast)*)
} }
} }
} }
} }
impl_visit!(bool, serialize_bool); impl_visit!(bool, serialize_bool);
impl_visit!(isize, serialize_isize); impl_visit!(isize, serialize_i64 as i64);
impl_visit!(i8, serialize_i8); impl_visit!(i8, serialize_i8);
impl_visit!(i16, serialize_i16); impl_visit!(i16, serialize_i16);
impl_visit!(i32, serialize_i32); impl_visit!(i32, serialize_i32);
impl_visit!(i64, serialize_i64); impl_visit!(i64, serialize_i64);
impl_visit!(usize, serialize_usize); impl_visit!(usize, serialize_u64 as u64);
impl_visit!(u8, serialize_u8); impl_visit!(u8, serialize_u8);
impl_visit!(u16, serialize_u16); impl_visit!(u16, serialize_u16);
impl_visit!(u32, serialize_u32); impl_visit!(u32, serialize_u32);
@@ -772,7 +766,7 @@ impl Serialize for path::Path {
{ {
match self.to_str() { match self.to_str() {
Some(s) => s.serialize(serializer), Some(s) => s.serialize(serializer),
None => Err(Error::custom("Path contains invalid UTF-8 characters")), None => Err(Error::custom("path contains invalid UTF-8 characters")),
} }
} }
} }
+525 -163
View File
@@ -1,14 +1,97 @@
//! Generic serialization framework. //! Generic data structure serialization framework.
//! # For Developers who want to serialize objects
//! Implement the `Serialize` trait for the type of objects you want to serialize. Call methods of
//! the `serializer` object. For which methods to call and how to do so, look at the documentation
//! of the `Serializer` trait.
//! //!
//! # For Serialization Format Developers //! The two most important traits in this module are `Serialize` and
//! Implement the `Serializer` trait for a structure that contains fields that enable it to write //! `Serializer`.
//! the serialization result to your target. When a method's argument is an object of type //!
//! `Serialize`, you can either forward the serializer object (`self`) or create a new one, //! - **A type that implements `Serialize` is a data structure** that can be
//! depending on the quirks of your format. //! serialized to any data format supported by Serde, and conversely
//! - **A type that implements `Serializer` is a data format** that can
//! serialize any data structure supported by Serde.
//!
//! # The Serialize trait
//!
//! Serde provides `Serialize` implementations for many Rust primitive and
//! standard library types. The complete list is below. All of these can be
//! serialized using Serde out of the box.
//!
//! Additionally, Serde provides a procedural macro called `serde_derive` to
//! automatically generate `Serialize` implementations for structs and enums in
//! your program. See the [codegen section of the manual][codegen] for how to
//! use this.
//!
//! In rare cases it may be necessary to implement `Serialize` manually for some
//! type in your program. See the [Implementing `Serialize`][impl-serialize]
//! section of the manual for more about this.
//!
//! Third-party crates may provide `Serialize` implementations for types that
//! they expose. For example the `linked-hash-map` crate provides a
//! `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
//! provides an implementation of `Serialize` for it.
//!
//! # The Serializer trait
//!
//! `Serializer` implementations are provided by third-party crates, for example
//! [`serde_json`][serde_json], [`serde_yaml`][serde_yaml] and
//! [`bincode`][bincode].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data-formats].
//!
//! # Implementations of Serialize provided by Serde
//!
//! - **Primitive types**:
//! - bool
//! - isize, i8, i16, i32, i64
//! - usize, u8, u16, u32, u64
//! - f32, f64
//! - char
//! - str
//! - &T and &mut T
//! - **Compound types**:
//! - [T]
//! - [T; 0] through [T; 32]
//! - tuples up to size 16
//! - **Common standard library types**:
//! - String
//! - Option\<T\>
//! - Result\<T, E\>
//! - PhantomData\<T\>
//! - **Wrapper types**:
//! - Box\<T\>
//! - Rc\<T\>
//! - Arc\<T\>
//! - Cow\<'a, T\>
//! - **Collection types**:
//! - BTreeMap\<K, V\>
//! - BTreeSet\<T\>
//! - BinaryHeap\<T\>
//! - HashMap\<K, V, H\>
//! - HashSet\<T, H\>
//! - LinkedList\<T\>
//! - VecDeque\<T\>
//! - Vec\<T\>
//! - EnumSet\<T\> (unstable)
//! - Range\<T\> (unstable)
//! - RangeInclusive\<T\> (unstable)
//! - **Miscellaneous standard library types**:
//! - Duration
//! - Path
//! - PathBuf
//! - NonZero\<T\> (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
//! - SocketAddr
//! - SocketAddrV4
//! - SocketAddrV6
//!
//! [codegen]: https://serde.rs/codegen.html
//! [impl-serialize]: https://serde.rs/impl-serialize.html
//! [serde_json]: https://github.com/serde-rs/json
//! [serde_yaml]: https://github.com/dtolnay/serde-yaml
//! [bincode]: https://github.com/TyOverby/bincode
//! [data-formats]: https://serde.rs/#data-formats
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error; use std::error;
@@ -20,52 +103,146 @@ use core::cell::RefCell;
use core::fmt::Display; use core::fmt::Display;
pub mod impls; mod impls;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// `Error` is a trait that allows a `Serialize` to generically create a /// Trait used by `Serialize` implementations to generically construct errors
/// `Serializer` error. /// belonging to the `Serializer` against which they are currently running.
pub trait Error: Sized + error::Error { pub trait Error: Sized + error::Error {
/// Raised when there is a general error when serializing a type. /// Raised when a `Serialize` implementation encounters a general error
/// while serializing a type.
///
/// The message should not be capitalized and should not end with a period.
///
/// For example, a filesystem `Path` may refuse to serialize itself if it
/// contains invalid UTF-8 data.
///
/// ```rust
/// # use serde::ser::{Serialize, Serializer, Error};
/// # struct Path;
/// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } }
/// impl Serialize for Path {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer
/// {
/// match self.to_str() {
/// Some(s) => s.serialize(serializer),
/// None => Err(Error::custom("path contains invalid UTF-8 characters")),
/// }
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self; fn custom<T: Display>(msg: T) -> Self;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can be serialized by a `Serializer`. /// An implementation of this trait is a **data structure** that can be
/// serialized into any data format supported by Serde.
///
/// Serde provides `Serialize` implementations for many Rust primitive and
/// standard library types. The complete list is [here][ser]. All of these can
/// be serialized using Serde out of the box.
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual][codegen] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`][impl-serialize]
/// section of the manual for more about this.
///
/// Third-party crates may provide `Serialize` implementations for types that
/// they expose. For example the `linked-hash-map` crate provides a
/// `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
/// provides an implementation of `Serialize` for it.
///
/// [ser]: https://docs.serde.rs/serde/ser/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [impl-serialize]: https://serde.rs/impl-serialize.html
pub trait Serialize { pub trait Serialize {
/// Serializes this value into this serializer. /// Serialize this value into the given Serde serializer.
///
/// See the [Implementing `Serialize`][impl-serialize] section of the manual
/// for more information about how to implement this method.
///
/// [impl-serialize]: https://serde.rs/impl-serialize.html
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer; where S: Serializer;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can serialize a stream of values into the underlying format. /// An implementation of this trait is a **data format** that can serialize any
/// data structure supported by Serde.
/// ///
/// # For `Serialize` Developers /// The role of this trait is to define the serialization half of the Serde data
/// Non-aggregate types like integers and strings can be serialized directly by calling the /// model, which is a way to categorize every Rust data structure into one of 28
/// appropriate function. For Aggregate types there's an initial `serialize_T` method that yields /// possible types. Each method of the `Serializer` trait corresponds to one of
/// a State object that you should not interact with. For each part of the aggregate there's a /// the types of the data model.
/// `serialize_T_elt` method that allows you to pass values or key/value pairs. The types of the
/// values or the keys may change between calls, but the serialization format may not necessarily
/// accept it. The `serialize_T_elt` method also takes a mutable reference to the state object.
/// Make sure that you always use the same state object and only the state object that was returned
/// by the `serialize_T` method. Finally, when your object is done, call the `serialize_T_end`
/// method and pass the state object by value
/// ///
/// # For Serialization Format Developers /// Implementations of `Serialize` map themselves into this data model by
/// If your format has different situations where it accepts different types, create a /// invoking exactly one of the `Serializer` methods.
/// `Serializer` for each situation. You can create the sub-`Serializer` in one of the aggregate ///
/// `serialize_T` methods and return it as a state object. Remember to also set the corresponding /// The types that make up the Serde data model are:
/// associated type `TState`. In the `serialize_T_elt` methods you will be given a mutable ///
/// reference to that state. You do not need to do any additional checks for the correctness of the /// - 12 primitive types:
/// state object, as it is expected that the user will not modify it. Due to the generic nature /// - bool
/// of the `Serialize` impls, modifying the object is impossible on stable Rust. /// - i8, i16, i32, i64
/// - u8, u16, u32, u64
/// - f32, f64
/// - char
/// - string
/// - byte array - [u8]
/// - option
/// - either none or some value
/// - unit
/// - unit is the type of () in Rust
/// - unit_struct
/// - for example `struct Unit` or `PhantomData<T>`
/// - unit_variant
/// - the `E::A` and `E::B` in `enum E { A, B }`
/// - newtype_struct
/// - for example `struct Millimeters(u8)`
/// - newtype_variant
/// - the `E::N` in `enum E { N(u8) }`
/// - seq
/// - a dynamically sized sequence of values, for example `Vec<T>` or
/// `HashSet<T>`
/// - seq_fixed_size
/// - a statically sized sequence of values for which the size will be known
/// at deserialization time without looking at the serialized data, for
/// example `[u64; 10]`
/// - tuple
/// - for example `(u8,)` or `(String, u64, Vec<T>)`
/// - tuple_struct
/// - for example `struct Rgb(u8, u8, u8)`
/// - tuple_variant
/// - the `E::T` in `enum E { T(u8, u8) }`
/// - map
/// - for example `BTreeMap<K, V>`
/// - struct
/// - a key-value pairing in which the keys will be known at deserialization
/// time without looking at the serialized data, for example `struct S { r:
/// u8, g: u8, b: u8 }`
/// - struct_variant
/// - the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`
///
/// Many Serde serializers produce text or binary data as output, for example
/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example
/// 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 {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// The output type produced by this `Serializer` during successful
/// `Serializer` should set `Ok = ()`. /// serialization. Most serializers that produce text or binary output
/// should set `Ok = ()` and serialize into an `io::Write` or buffer
/// contained within the `Serializer` instance. Serializers that build
/// in-memory data structures may be simplified by using `Ok` to propagate
/// the data structure around.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// The error type when some error occurs during serialization.
@@ -99,75 +276,85 @@ pub trait Serializer {
/// content of the struct variant. /// content of the struct variant.
type SerializeStructVariant: SerializeStructVariant<Ok=Self::Ok, Error=Self::Error>; type SerializeStructVariant: SerializeStructVariant<Ok=Self::Ok, Error=Self::Error>;
/// Serializes a `bool` value. /// Serialize a `bool` value.
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>; fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
/// Serializes an `isize` value. If the format does not differentiate /// Serialize an `i8` value.
/// between `isize` and `i64`, a reasonable implementation would be to cast ///
/// the value to `i64` and forward to `serialize_i64`. /// If the format does not differentiate between `i8` and `i64`, a
fn serialize_isize(self, v: isize) -> Result<Self::Ok, Self::Error>; /// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
/// Serializes an `i8` value. If the format does not differentiate between
/// `i8` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>; fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i16` value. If the format does not differentiate between /// Serialize an `i16` value.
/// `i16` and `i64`, a reasonable implementation would be to cast the value ///
/// to `i64` and forward to `serialize_i64`. /// If the format does not differentiate between `i16` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>; fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i32` value. If the format does not differentiate between /// Serialize an `i32` value.
/// `i32` and `i64`, a reasonable implementation would be to cast the value ///
/// to `i64` and forward to `serialize_i64`. /// If the format does not differentiate between `i32` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>; fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i64` value. /// Serialize an `i64` value.
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>; fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
/// Serializes a `usize` value. If the format does not differentiate between /// Serialize a `u8` value.
/// `usize` and `u64`, a reasonable implementation would be to cast the ///
/// value to `u64` and forward to `serialize_u64`. /// If the format does not differentiate between `u8` and `u64`, a
fn serialize_usize(self, v: usize) -> Result<Self::Ok, Self::Error>; /// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
/// Serializes a `u8` value. If the format does not differentiate between
/// `u8` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>; fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
/// Serializes a `u16` value. If the format does not differentiate between /// Serialize a `u16` value.
/// `u16` and `u64`, a reasonable implementation would be to cast the value ///
/// to `u64` and forward to `serialize_u64`. /// If the format does not differentiate between `u16` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>; fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
/// Serializes a `u32` value. If the format does not differentiate between /// Serialize a `u32` value.
/// `u32` and `u64`, a reasonable implementation would be to cast the value ///
/// to `u64` and forward to `serialize_u64`. /// If the format does not differentiate between `u32` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>; fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
/// `Serializes a `u64` value. /// Serialize a `u64` value.
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>; fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
/// Serializes an `f32` value. If the format does not differentiate between /// Serialize an `f32` value.
/// `f32` and `f64`, a reasonable implementation would be to cast the value ///
/// to `f64` and forward to `serialize_f64`. /// If the format does not differentiate between `f32` and `f64`, a
/// reasonable implementation would be to cast the value to `f64` and
/// forward to `serialize_f64`.
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>; fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
/// Serializes an `f64` value. /// Serialize an `f64` value.
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>; fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
/// Serializes a character. If the format does not support characters, /// Serialize a character.
/// it is reasonable to serialize it as a single element `str` or a `u32`. ///
/// If the format does not support characters, it is reasonable to serialize
/// it as a single element `str` or a `u32`.
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>; fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
/// Serializes a `&str`. /// Serialize a `&str`.
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error>; fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error>;
/// Serialize a chunk of raw byte data.
///
/// Enables serializers to serialize byte slices more compactly or more /// Enables serializers to serialize byte slices more compactly or more
/// efficiently than other types of slices. If no efficient implementation /// efficiently than other types of slices. If no efficient implementation
/// is available, a reasonable implementation would be to forward to /// is available, a reasonable implementation would be to forward to
/// `serialize_seq`. If forwarded, the implementation looks usually just like this: /// `serialize_seq`. If forwarded, the implementation looks usually just
/// ```rust /// like this:
///
/// ```rust,ignore
/// let mut seq = self.serialize_seq(Some(value.len()))?; /// let mut seq = self.serialize_seq(Some(value.len()))?;
/// for b in value { /// for b in value {
/// seq.serialize_element(b)?; /// seq.serialize_element(b)?;
@@ -176,19 +363,40 @@ pub trait Serializer {
/// ``` /// ```
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error>; fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error>;
/// Serializes a `()` value. It's reasonable to just not serialize anything. /// Serialize a `None` value.
fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
/// Serialize a `Some(T)` value.
fn serialize_some<T: ?Sized + Serialize>(
self,
value: &T,
) -> Result<Self::Ok, Self::Error>;
/// Serialize a `()` value.
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>; fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
/// Serializes a unit struct value. A reasonable implementation would be to /// Serialize a unit struct like `struct Unit` or `PhantomData<T>`.
/// forward to `serialize_unit`. ///
/// A reasonable implementation would be to forward to `serialize_unit`.
fn serialize_unit_struct( fn serialize_unit_struct(
self, self,
name: &'static str, name: &'static str,
) -> Result<Self::Ok, Self::Error>; ) -> Result<Self::Ok, Self::Error>;
/// Serializes a unit variant, otherwise known as a variant with no /// Serialize a unit variant like `E::A` in `enum E { A, B }`.
/// arguments. A reasonable implementation would be to forward to ///
/// `serialize_unit`. /// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant.
///
/// A reasonable implementation would be to forward to `serialize_unit`.
///
/// ```rust,ignore
/// match *self {
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
/// E::B => serializer.serialize_unit_variant("E", 1, "B"),
/// }
/// ```
fn serialize_unit_variant( fn serialize_unit_variant(
self, self,
name: &'static str, name: &'static str,
@@ -196,19 +404,32 @@ pub trait Serializer {
variant: &'static str, variant: &'static str,
) -> Result<Self::Ok, Self::Error>; ) -> Result<Self::Ok, Self::Error>;
/// Allows a tuple struct with a single element, also known as a newtype /// Serialize a newtype struct like `struct Millimeters(u8)`.
/// struct, to be more efficiently serialized than a tuple struct with ///
/// multiple items. A reasonable implementation would be to forward to /// Serializers are encouraged to treat newtype structs as insignificant
/// `serialize_tuple_struct` or to just serialize the inner value without wrapping. /// wrappers around the data they contain. A reasonable implementation would
/// be to forward to `value.serialize(self)`.
///
/// ```rust,ignore
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
/// ```
fn serialize_newtype_struct<T: ?Sized + Serialize>( fn serialize_newtype_struct<T: ?Sized + Serialize>(
self, self,
name: &'static str, name: &'static str,
value: &T, value: &T,
) -> Result<Self::Ok, Self::Error>; ) -> Result<Self::Ok, Self::Error>;
/// Allows a variant with a single item to be more efficiently serialized /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`.
/// than a variant with multiple items. A reasonable implementation would be ///
/// to forward to `serialize_tuple_variant`. /// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant. The `value` is the data contained within this newtype variant.
///
/// ```rust,ignore
/// match *self {
/// E::N(ref n) => serializer.serialize_newtype_variant("E", 0, "N", n),
/// }
/// ```
fn serialize_newtype_variant<T: ?Sized + Serialize>( fn serialize_newtype_variant<T: ?Sized + Serialize>(
self, self,
name: &'static str, name: &'static str,
@@ -217,53 +438,96 @@ pub trait Serializer {
value: &T, value: &T,
) -> Result<Self::Ok, Self::Error>; ) -> Result<Self::Ok, Self::Error>;
/// Serializes a `None` value. /// Begin to serialize a dynamically sized sequence. This call must be
fn serialize_none(self) -> Result<Self::Ok, Self::Error>; /// followed by zero or more calls to `serialize_element`, then a call to
/// `end`.
/// Serializes a `Some(...)` value. ///
fn serialize_some<T: ?Sized + Serialize>( /// The argument is the number of elements in the sequence, which may or may
self, /// not be computable before the sequence is iterated. Some serializers only
value: &T, /// support sequences whose length is known up front.
) -> Result<Self::Ok, Self::Error>; ///
/// ```rust,ignore
/// Begins to serialize a sequence. This call must be followed by zero or /// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// more calls to `serialize_seq_elt`, then a call to `serialize_seq_end`. /// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq( fn serialize_seq(
self, self,
len: Option<usize>, len: Option<usize>,
) -> Result<Self::SerializeSeq, Self::Error>; ) -> Result<Self::SerializeSeq, Self::Error>;
/// Begins to serialize a sequence whose length will be known at /// Begin to serialize a statically sized sequence whose length will be
/// deserialization time. This call must be followed by zero or more calls /// known at deserialization time without looking at the serialized data.
/// to `serialize_seq_elt`, then a call to `serialize_seq_end`. A reasonable /// This call must be followed by zero or more calls to `serialize_element`,
/// implementation would be to forward to `serialize_seq`. /// then a call to `end`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq_fixed_size(self.len())?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq_fixed_size( fn serialize_seq_fixed_size(
self, self,
size: usize, size: usize,
) -> Result<Self::SerializeSeq, Self::Error>; ) -> Result<Self::SerializeSeq, Self::Error>;
/// Begins to serialize a tuple. This call must be followed by zero or more /// Begin to serialize a tuple. This call must be followed by zero or more
/// calls to `serialize_tuple_elt`, then a call to `serialize_tuple_end`. A /// calls to `serialize_field`, then a call to `end`.
/// reasonable implementation would be to forward to `serialize_seq`. ///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
fn serialize_tuple( fn serialize_tuple(
self, self,
len: usize, len: usize,
) -> Result<Self::SerializeTuple, Self::Error>; ) -> Result<Self::SerializeTuple, Self::Error>;
/// Begins to serialize a tuple struct. This call must be followed by zero /// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This
/// or more calls to `serialize_tuple_struct_elt`, then a call to /// call must be followed by zero or more calls to `serialize_field`, then a
/// `serialize_tuple_struct_end`. A reasonable implementation would be to /// call to `end`.
/// forward to `serialize_tuple`. ///
/// The `name` is the name of the tuple struct and the `len` is the number
/// of data fields that will be serialized.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
fn serialize_tuple_struct( fn serialize_tuple_struct(
self, self,
name: &'static str, name: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error>; ) -> Result<Self::SerializeTupleStruct, Self::Error>;
/// Begins to serialize a tuple variant. This call must be followed by zero /// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8)
/// or more calls to `serialize_tuple_variant_elt`, then a call to /// }`. This call must be followed by zero or more calls to
/// `serialize_tuple_variant_end`. A reasonable implementation would be to /// `serialize_field`, then a call to `end`.
/// forward to `serialize_tuple_struct`. ///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
fn serialize_tuple_variant( fn serialize_tuple_variant(
self, self,
name: &'static str, name: &'static str,
@@ -272,25 +536,65 @@ pub trait Serializer {
len: usize, len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error>; ) -> Result<Self::SerializeTupleVariant, Self::Error>;
/// Begins to serialize a map. This call must be followed by zero or more /// Begin to serialize a map. This call must be followed by zero or more
/// calls to `serialize_map_key` and `serialize_map_value`, then a call to /// calls to `serialize_key` and `serialize_value`, then a call to `end`.
/// `serialize_map_end`. ///
/// The argument is the number of elements in the map, which may or may not
/// be computable before the map is iterated. Some serializers only support
/// maps whose length is known up front.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_key(k)?;
/// map.serialize_value(v)?;
/// }
/// map.end()
/// ```
fn serialize_map( fn serialize_map(
self, self,
len: Option<usize>, len: Option<usize>,
) -> Result<Self::SerializeMap, Self::Error>; ) -> Result<Self::SerializeMap, Self::Error>;
/// Begins to serialize a struct. This call must be followed by zero or more /// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`.
/// calls to `serialize_struct_elt`, then a call to `serialize_struct_end`. /// This call must be followed by zero or more calls to `serialize_field`,
/// then a call to `end`.
///
/// The `name` is the name of the struct and the `len` is the number of
/// data fields that will be serialized.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
fn serialize_struct( fn serialize_struct(
self, self,
name: &'static str, name: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeStruct, Self::Error>; ) -> Result<Self::SerializeStruct, Self::Error>;
/// Begins to serialize a struct variant. This call must be followed by zero /// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8,
/// or more calls to `serialize_struct_variant_elt`, then a call to /// g: u8, b: u8 } }`. This call must be followed by zero or more calls to
/// `serialize_struct_variant_end`. /// `serialize_field`, then a call to `end`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
fn serialize_struct_variant( fn serialize_struct_variant(
self, self,
name: &'static str, name: &'static str,
@@ -302,76 +606,115 @@ pub trait Serializer {
/// Returned from `Serializer::serialize_seq` and /// Returned from `Serializer::serialize_seq` and
/// `Serializer::serialize_seq_fixed_size`. /// `Serializer::serialize_seq_fixed_size`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
pub trait SerializeSeq { pub trait SerializeSeq {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeSeq` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serializes a sequence element. /// Serialize a sequence element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>; fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a sequence. /// Finish serializing a sequence.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_tuple`. /// Returned from `Serializer::serialize_tuple`.
///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
pub trait SerializeTuple { pub trait SerializeTuple {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeTuple` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serializes a tuple element. /// Serialize a tuple element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>; fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple. /// Finish serializing a tuple.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_tuple_struct`. /// Returned from `Serializer::serialize_tuple_struct`.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
pub trait SerializeTupleStruct { pub trait SerializeTupleStruct {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeTupleStruct` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serializes a tuple struct element. /// Serialize a tuple struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>; fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple struct. /// Finish serializing a tuple struct.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_tuple_variant`. /// Returned from `Serializer::serialize_tuple_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
pub trait SerializeTupleVariant { pub trait SerializeTupleVariant {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeTupleVariant` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serializes a tuple variant element. /// Serialize a tuple variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>; fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple variant. /// Finish serializing a tuple variant.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_map`. /// Returned from `Serializer::serialize_map`.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_key(k)?;
/// map.serialize_value(v)?;
/// }
/// map.end()
/// ```
pub trait SerializeMap { pub trait SerializeMap {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeMap` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serialize a map key. /// Serialize a map key.
@@ -380,52 +723,71 @@ pub trait SerializeMap {
/// Serialize a map value. /// Serialize a map value.
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>; fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a map. /// Finish serializing a map.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_struct`. /// Returned from `Serializer::serialize_struct`.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
pub trait SerializeStruct { pub trait SerializeStruct {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeStruct` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serializes a struct field. /// Serialize a struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>; fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a struct. /// Finish serializing a struct.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// Returned from `Serializer::serialize_struct_variant`. /// Returned from `Serializer::serialize_struct_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
pub trait SerializeStructVariant { pub trait SerializeStructVariant {
/// Trickery to enforce correct use of the `Serialize` trait. Every /// Must match the `Ok` type of our `Serializer`.
/// `SerializeStructVariant` should set `Ok = ()`.
type Ok; type Ok;
/// The error type when some error occurs during serialization. /// Must match the `Error` type of our `Serializer`.
type Error: Error; type Error: Error;
/// Serialize a struct variant element. /// Serialize a struct variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>; fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a struct variant. /// Finish serializing a struct variant.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
/// A wrapper type for iterators that implements `Serialize` for iterators whose items implement /// A wrapper type for iterators that implements `Serialize` for iterators whose
/// `Serialize`. Don't use multiple times. Create new versions of this with the `iterator` function /// items implement `Serialize`. Don't use multiple times. Create new versions
/// every time you want to serialize an iterator. /// of this with the `serde::ser::iterator` function every time you want to
/// serialize an iterator.
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
pub struct Iterator<I>(RefCell<Option<I>>) pub struct Iterator<I>(RefCell<Option<I>>)
where <I as IntoIterator>::Item: Serialize, where <I as IntoIterator>::Item: Serialize,
I: IntoIterator; I: IntoIterator;
/// Creates a temporary type that can be passed to any function expecting a `Serialize` and will /// Create a wrapper type that can be passed to any function expecting a
/// serialize the given iterator as a sequence /// `Serialize` and will serialize the given iterator as a sequence.
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
pub fn iterator<I>(iter: I) -> Iterator<I> pub fn iterator<I>(iter: I) -> Iterator<I>
where <I as IntoIterator>::Item: Serialize, where <I as IntoIterator>::Item: Serialize,
+4 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_codegen" name = "serde_codegen"
version = "0.9.0-rc3" version = "0.9.0-rc4"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework" description = "Macros to auto-generate implementations for the serde framework"
@@ -27,3 +27,6 @@ serde_codegen_internals = { version = "=0.11.3", default-features = false, path
syn = { version = "0.10", features = ["aster", "visit"] } syn = { version = "0.10", features = ["aster", "visit"] }
syntex = { version = "^0.54.0", optional = true } syntex = { version = "^0.54.0", optional = true }
syntex_syntax = { version = "^0.54.0", optional = true } syntex_syntax = { version = "^0.54.0", optional = true }
[badges]
travis-ci = { repository = "serde-rs/serde" }
+4 -4
View File
@@ -692,11 +692,11 @@ fn deserialize_field_visitor(
Some(quote!(__ignore,)) Some(quote!(__ignore,))
}; };
let visit_usize = if is_variant { let visit_index = if is_variant {
let variant_indices = 0usize..; let variant_indices = 0u32..;
let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
Some(quote! { Some(quote! {
fn visit_usize<__E>(self, value: usize) -> _serde::export::Result<__Field, __E> fn visit_u32<__E>(self, value: u32) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error where __E: _serde::de::Error
{ {
match value { match value {
@@ -758,7 +758,7 @@ fn deserialize_field_visitor(
formatter.write_str("field name") formatter.write_str("field name")
} }
#visit_usize #visit_index
fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E> fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error where __E: _serde::de::Error
-1
View File
@@ -12,7 +12,6 @@ extern crate serde_codegen_internals as internals;
extern crate syntex; extern crate syntex;
#[cfg(feature = "with-syntex")] #[cfg(feature = "with-syntex")]
#[macro_use]
extern crate syntex_syntax as syntax; extern crate syntex_syntax as syntax;
extern crate syn; extern crate syn;
+3
View File
@@ -16,3 +16,6 @@ unstable-testing = ["clippy"]
[dependencies] [dependencies]
clippy = { version = "^0.*", optional = true } clippy = { version = "^0.*", optional = true }
syn = "0.10" syn = "0.10"
[badges]
travis-ci = { repository = "serde-rs/serde" }
+7 -4
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "0.9.0-rc3" version = "0.9.0-rc4"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -10,12 +10,15 @@ documentation = "https://serde.rs/codegen.html"
keywords = ["serde", "serialization"] keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"] include = ["Cargo.toml", "src/**/*.rs"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
[lib] [lib]
name = "serde_derive" name = "serde_derive"
proc-macro = true proc-macro = true
[dependencies.serde_codegen] [dependencies.serde_codegen]
version = "=0.9.0-rc3" version = "=0.9.0-rc4"
path = "../serde_codegen" path = "../serde_codegen"
default-features = false default-features = false
features = ["with-syn"] features = ["with-syn"]
@@ -23,5 +26,5 @@ features = ["with-syn"]
[dev-dependencies] [dev-dependencies]
compiletest_rs = "^0.2.0" compiletest_rs = "^0.2.0"
fnv = "1.0" fnv = "1.0"
serde = { version = "0.9.0-rc3", path = "../serde" } serde = { version = "0.9.0-rc4", path = "../serde" }
serde_test = { version = "0.9.0-rc3", path = "../serde_test" } serde_test = { version = "0.9.0-rc4", path = "../serde_test" }
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive_tests_no_std" name = "serde_derive_tests_no_std"
version = "0.9.0-rc3" version = "0.9.0-rc4"
publish = false publish = false
[dependencies] [dependencies]
+5 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "0.9.0-rc3" version = "0.9.0-rc4"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
@@ -12,4 +12,7 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"] include = ["Cargo.toml", "src/**/*.rs"]
[dependencies] [dependencies]
serde = { version = "0.9.0-rc3", path = "../serde" } serde = { version = "0.9.0-rc4", path = "../serde" }
[badges]
travis-ci = { repository = "serde-rs/serde" }
-10
View File
@@ -225,26 +225,16 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
where __V: de::Visitor { where __V: de::Visitor {
self.deserialize(visitor) self.deserialize(visitor)
} }
fn deserialize_usize<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize_isize<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
where V: Visitor, where V: Visitor,
{ {
match self.tokens.next() { match self.tokens.next() {
Some(Token::Bool(v)) => visitor.visit_bool(v), Some(Token::Bool(v)) => visitor.visit_bool(v),
Some(Token::Isize(v)) => visitor.visit_isize(v),
Some(Token::I8(v)) => visitor.visit_i8(v), Some(Token::I8(v)) => visitor.visit_i8(v),
Some(Token::I16(v)) => visitor.visit_i16(v), Some(Token::I16(v)) => visitor.visit_i16(v),
Some(Token::I32(v)) => visitor.visit_i32(v), Some(Token::I32(v)) => visitor.visit_i32(v),
Some(Token::I64(v)) => visitor.visit_i64(v), Some(Token::I64(v)) => visitor.visit_i64(v),
Some(Token::Usize(v)) => visitor.visit_usize(v),
Some(Token::U8(v)) => visitor.visit_u8(v), Some(Token::U8(v)) => visitor.visit_u8(v),
Some(Token::U16(v)) => visitor.visit_u16(v), Some(Token::U16(v)) => visitor.visit_u16(v),
Some(Token::U32(v)) => visitor.visit_u32(v), Some(Token::U32(v)) => visitor.visit_u32(v),
-10
View File
@@ -46,11 +46,6 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(()) Ok(())
} }
fn serialize_isize(self, v: isize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Isize(v)));
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<(), Error> { fn serialize_i8(self, v: i8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I8(v))); assert_eq!(self.tokens.next(), Some(&Token::I8(v)));
Ok(()) Ok(())
@@ -71,11 +66,6 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(()) Ok(())
} }
fn serialize_usize(self, v: usize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Usize(v)));
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<(), Error> { fn serialize_u8(self, v: u8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U8(v))); assert_eq!(self.tokens.next(), Some(&Token::U8(v)));
Ok(()) Ok(())
-2
View File
@@ -1,12 +1,10 @@
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> { pub enum Token<'a> {
Bool(bool), Bool(bool),
Isize(isize),
I8(i8), I8(i8),
I16(i16), I16(i16),
I32(i32), I32(i32),
I64(i64), I64(i64),
Usize(usize),
U8(u8), U8(u8),
U16(u16), U16(u16),
U32(u32), U32(u32),
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_testing" name = "serde_testing"
version = "0.9.0-rc3" version = "0.9.0-rc4"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
+2 -6
View File
@@ -155,12 +155,10 @@ declare_tests! {
false => &[Token::Bool(false)], false => &[Token::Bool(false)],
} }
test_isize { test_isize {
0isize => &[Token::Isize(0)],
0isize => &[Token::I8(0)], 0isize => &[Token::I8(0)],
0isize => &[Token::I16(0)], 0isize => &[Token::I16(0)],
0isize => &[Token::I32(0)], 0isize => &[Token::I32(0)],
0isize => &[Token::I64(0)], 0isize => &[Token::I64(0)],
0isize => &[Token::Usize(0)],
0isize => &[Token::U8(0)], 0isize => &[Token::U8(0)],
0isize => &[Token::U16(0)], 0isize => &[Token::U16(0)],
0isize => &[Token::U32(0)], 0isize => &[Token::U32(0)],
@@ -169,14 +167,12 @@ declare_tests! {
0isize => &[Token::F64(0.)], 0isize => &[Token::F64(0.)],
} }
test_ints { test_ints {
0isize => &[Token::Isize(0)],
0i8 => &[Token::I8(0)], 0i8 => &[Token::I8(0)],
0i16 => &[Token::I16(0)], 0i16 => &[Token::I16(0)],
0i32 => &[Token::I32(0)], 0i32 => &[Token::I32(0)],
0i64 => &[Token::I64(0)], 0i64 => &[Token::I64(0)],
} }
test_uints { test_uints {
0usize => &[Token::Usize(0)],
0u8 => &[Token::U8(0)], 0u8 => &[Token::U8(0)],
0u16 => &[Token::U16(0)], 0u16 => &[Token::U16(0)],
0u32 => &[Token::U32(0)], 0u32 => &[Token::U32(0)],
@@ -777,7 +773,7 @@ declare_tests! {
test_enum_unit_usize { test_enum_unit_usize {
Enum::Unit => &[ Enum::Unit => &[
Token::EnumStart("Enum"), Token::EnumStart("Enum"),
Token::Usize(0), Token::U32(0),
Token::Unit, Token::Unit,
], ],
} }
@@ -935,7 +931,7 @@ declare_error_tests! {
test_enum_out_of_range<Enum> { test_enum_out_of_range<Enum> {
&[ &[
Token::EnumStart("Enum"), Token::EnumStart("Enum"),
Token::Usize(4), Token::U32(4),
Token::Unit, Token::Unit,
], ],
Error::Message("invalid value: integer `4`, expected variant index 0 <= i < 4".into()), Error::Message("invalid value: integer `4`, expected variant index 0 <= i < 4".into()),
+2 -4
View File
@@ -60,14 +60,12 @@ declare_ser_tests! {
false => &[Token::Bool(false)], false => &[Token::Bool(false)],
} }
test_isizes { test_isizes {
0isize => &[Token::Isize(0)],
0i8 => &[Token::I8(0)], 0i8 => &[Token::I8(0)],
0i16 => &[Token::I16(0)], 0i16 => &[Token::I16(0)],
0i32 => &[Token::I32(0)], 0i32 => &[Token::I32(0)],
0i64 => &[Token::I64(0)], 0i64 => &[Token::I64(0)],
} }
test_usizes { test_usizes {
0usize => &[Token::Usize(0)],
0u8 => &[Token::U8(0)], 0u8 => &[Token::U8(0)],
0u16 => &[Token::U16(0)], 0u16 => &[Token::U16(0)],
0u32 => &[Token::U32(0)], 0u32 => &[Token::U32(0)],
@@ -432,7 +430,7 @@ fn test_cannot_serialize_paths() {
assert_ser_tokens_error( assert_ser_tokens_error(
&Path::new(path), &Path::new(path),
&[], &[],
Error::Message("Path contains invalid UTF-8 characters".to_owned())); Error::Message("path contains invalid UTF-8 characters".to_owned()));
let mut path_buf = PathBuf::new(); let mut path_buf = PathBuf::new();
path_buf.push(path); path_buf.push(path);
@@ -440,7 +438,7 @@ fn test_cannot_serialize_paths() {
assert_ser_tokens_error( assert_ser_tokens_error(
&path_buf, &path_buf,
&[], &[],
Error::Message("Path contains invalid UTF-8 characters".to_owned())); Error::Message("path contains invalid UTF-8 characters".to_owned()));
} }
#[test] #[test]