diff --git a/serde/Cargo.toml b/serde/Cargo.toml index d621bc24..89f3ce12 100644 --- a/serde/Cargo.toml +++ b/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "serde" -version = "0.5.3" +version = "0.6.0" authors = ["Erick Tryzelaar "] license = "MIT/Apache-2.0" description = "A generic serialization/deserialization framework" diff --git a/serde/src/buf.rs b/serde/src/buf.rs deleted file mode 100644 index 4dd41aaf..00000000 --- a/serde/src/buf.rs +++ /dev/null @@ -1,94 +0,0 @@ -use std::cmp; -use std::io; -use std::slice; - -trait IntoBufRead { - type IntoBuf: io::BufRead + BufReadExt; - - fn into_buf_read(self) -> Self::IntoBuf; -} - -trait BufReadExt { - fn get_buf(&self) -> &[u8]; - fn read_u8(&mut self) -> io::Result>; -} - -struct SliceReader<'a> { - buf: &'a [u8], -} - -impl<'a> io::Read for SliceReader<'a> { - #[inline] - fn read(&mut self, buf: &mut [u8]) -> io::Result { - let amt = cmp::min(buf.len(), self.buf.len()); - let (a, b) = self.buf.split_at(amt); - slice::bytes::copy_memory(buf, a); - *self.buf = b; - Ok(amt) - } -} - -impl<'a> io::BufRead for SliceReader<'a> { - fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) } - fn consume(&mut self, amt: usize) { *self.buf = &self.buf[amt..]; } -} - -impl<'a> BufReadExt for SliceReader<'a> { - fn get_buf(&self) -> &[u8] { self.buf } - fn read_u8(&mut self) -> io::Result> { - let byte = self.buf.get(0); - *self.buf = &self.buf[1..]; - byte - } -} - -struct BufReader { - inner: R, - buf: io::Cursor>, -} - -impl BufReader where R: io::Read { - fn new(inner: R) -> Self { - BufferedReader::with_capacity(io::DEFAULT_BUF_SIZE, inner) - } - - fn new(cap: usize, inner: R) -> Self { - BufferedReader { - inner: inner, - buf: io::Cursor::new(Vec::with_capacity(cap)), - } - } - - fn into_inner(self) -> R { - self.inner - } -} - -impl Read for BufReader where R: io::Read { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - // If we don't have any buffered data and we're doing a massive read - // (larger than our internal buffer), bypass our internal buffer - // entirely. - if self.buf.get_ref().len() == self.buf.position() as usize && - buf.len() >= self.buf.get_ref().capacity() { - return self.inner.read(buf); - } - try!(self.fill_buf()); - self.buf.read(buf) - } -} - -impl BufReadExt for BufReader { - fn get_buf(&self) -> &[u8] { - self.buf.get_ref() - } - - fn read_u8(&mut self) -> io::Result> { - if self.buf.get_ref().len() == self.buf.position() as usize { - - } - let byte = self.buf.get(0); - *self.buf = &self.buf[1..]; - byte - } -} diff --git a/serde/src/bytes.rs b/serde/src/bytes.rs index b3e02711..6a51bf18 100644 --- a/serde/src/bytes.rs +++ b/serde/src/bytes.rs @@ -60,19 +60,21 @@ impl<'a> ser::Serialize for Bytes<'a> { /////////////////////////////////////////////////////////////////////////////// -/// `ByteBuf` wraps a `Vec` in order to hook into serialize and from deserialize a byte array. +/// `ByteBuf` wraps a `Vec` and serializes as a byte array. #[derive(Clone, Eq, Hash, PartialEq, PartialOrd, Ord)] pub struct ByteBuf { bytes: Vec, } impl ByteBuf { + /// Construct a new, empty `ByteBuf`. pub fn new() -> Self { ByteBuf { bytes: Vec::new(), } } + /// Construct a new, empty `ByteBuf` with the specified capacity. pub fn with_capacity(cap: usize) -> Self { ByteBuf { bytes: Vec::with_capacity(cap) @@ -142,6 +144,7 @@ impl ser::Serialize for ByteBuf { } } +/// This type implements the `serde::de::Visitor` trait for a `ByteBuf`. pub struct ByteBufVisitor; impl de::Visitor for ByteBufVisitor { diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index b9543c83..2ae1d5bf 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -1,3 +1,5 @@ +//! This module contains `Deserialize` and `Visitor` implementations. + use std::borrow::Cow; use std::collections::{ BinaryHeap, @@ -39,6 +41,7 @@ use de::{ /////////////////////////////////////////////////////////////////////////////// +/// A visitor that produces a `()`. pub struct UnitVisitor; impl Visitor for UnitVisitor { @@ -67,6 +70,7 @@ impl Deserialize for () { /////////////////////////////////////////////////////////////////////////////// +/// A visitor that produces a `bool`. pub struct BoolVisitor; impl Visitor for BoolVisitor { @@ -113,11 +117,13 @@ macro_rules! impl_deserialize_num_method { } } +/// A visitor that produces a primitive type. pub struct PrimitiveVisitor { marker: PhantomData, } impl PrimitiveVisitor { + /// Construct a new `PrimitiveVisitor`. #[inline] pub fn new() -> Self { PrimitiveVisitor { @@ -300,7 +306,7 @@ impl Deserialize for Option where T: Deserialize { /////////////////////////////////////////////////////////////////////////////// -macro_rules! set_impl { +macro_rules! seq_impl { ( $ty:ty, < $($constraints:ident),* >, @@ -310,11 +316,13 @@ macro_rules! set_impl { $with_capacity:expr, $insert:expr ) => { + /// A visitor that produces a sequence. pub struct $visitor_name { marker: PhantomData, } impl $visitor_name { + /// Construct a new sequence visitor. pub fn new() -> Self { $visitor_name { marker: PhantomData, @@ -362,7 +370,7 @@ macro_rules! set_impl { } } -set_impl!( +seq_impl!( BinaryHeap, , BinaryHeapVisitor, @@ -371,7 +379,7 @@ set_impl!( BinaryHeap::with_capacity(visitor.size_hint().0), BinaryHeap::push); -set_impl!( +seq_impl!( BTreeSet, , BTreeSetVisitor, @@ -381,7 +389,7 @@ set_impl!( BTreeSet::insert); #[cfg(feature = "nightly")] -set_impl!( +seq_impl!( EnumSet, , EnumSetVisitor, @@ -390,7 +398,7 @@ set_impl!( EnumSet::new(), EnumSet::insert); -set_impl!( +seq_impl!( LinkedList, , LinkedListVisitor, @@ -399,7 +407,7 @@ set_impl!( LinkedList::new(), LinkedList::push_back); -set_impl!( +seq_impl!( HashSet, , HashSetVisitor, @@ -408,7 +416,7 @@ set_impl!( HashSet::with_capacity(visitor.size_hint().0), HashSet::insert); -set_impl!( +seq_impl!( Vec, , VecVisitor, @@ -417,7 +425,7 @@ set_impl!( Vec::with_capacity(visitor.size_hint().0), Vec::push); -set_impl!( +seq_impl!( VecDeque, , VecDequeVisitor, @@ -433,6 +441,7 @@ struct ArrayVisitor0 { } impl ArrayVisitor0 { + /// Construct a `ArrayVisitor0`. pub fn new() -> Self { ArrayVisitor0 { marker: PhantomData, @@ -477,6 +486,7 @@ macro_rules! array_impls { } impl $visitor { + /// Construct a `ArrayVisitor*`. pub fn new() -> Self { $visitor { marker: PhantomData @@ -566,6 +576,7 @@ macro_rules! tuple_impls { () => {}; ($($len:expr => $visitor:ident => ($($name:ident),+),)+) => { $( + /// Construct a tuple visitor. pub struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, } @@ -573,6 +584,7 @@ macro_rules! tuple_impls { impl< $($name: Deserialize,)+ > $visitor<$($name,)+> { + /// Construct a `TupleVisitor*`. pub fn new() -> Self { $visitor { marker: PhantomData } } @@ -643,11 +655,13 @@ macro_rules! map_impl { $with_capacity:expr, $insert:expr ) => { + /// A visitor that produces a map. pub struct $visitor_name { marker: PhantomData<$ty>, } impl $visitor_name { + /// Construct a `MapVisitor*`. pub fn new() -> Self { $visitor_name { marker: PhantomData, diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 2be58104..51626a4e 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -34,40 +34,100 @@ pub trait Error: Sized { /// `Type` represents all the primitive types that can be deserialized. This is used by /// `Error::kind_mismatch`. pub enum Type { + /// Represents a `bool` type. Bool, + + /// Represents a `usize` type. Usize, + + /// Represents a `u8` type. U8, + + /// Represents a `u16` type. U16, + + /// Represents a `u32` type. U32, + + /// Represents a `u64` type. U64, + + /// Represents a `isize` type. Isize, + + /// Represents a `i8` type. I8, + + /// Represents a `i16` type. I16, + + /// Represents a `i32` type. I32, + + /// Represents a `i64` type. I64, + + /// Represents a `f32` type. F32, + + /// Represents a `f64` type. F64, + + /// Represents a `char` type. Char, + + /// Represents a `&str` type. Str, + + /// Represents a `String` type. String, + + /// Represents a `()` type. Unit, + + /// Represents an `Option` type. Option, + + /// Represents a sequence type. Seq, + + /// Represents a map type. Map, + + /// Represents a unit struct type. UnitStruct, + + /// Represents a newtype type. NewtypeStruct, + + /// Represents a tuple struct type. TupleStruct, + + /// Represents a struct type. Struct, + + /// Represents a tuple type. Tuple, + + /// Represents an `enum` type. Enum, + + /// Represents a struct variant. StructVariant, + + /// Represents a tuple variant. TupleVariant, + + /// Represents a unit variant. UnitVariant, + + /// Represents a `&[u8]` type. Bytes, } /////////////////////////////////////////////////////////////////////////////// +/// `Deserialize` represents a type that can be deserialized. pub trait Deserialize: Sized { /// Deserialize this value given this `Deserializer`. fn deserialize(deserializer: &mut D) -> Result @@ -89,6 +149,7 @@ pub trait Deserialize: Sized { /// supporting the `visit_*` types is that it does not allow for deserializing into a generic /// `json::Value`-esque type. pub trait Deserializer { + /// The error type that can be returned if some error occurs during deserialization. type Error: Error; /// This method walks a visitor through a value as it is being deserialized. @@ -349,87 +410,103 @@ pub trait Deserializer { /////////////////////////////////////////////////////////////////////////////// +/// This trait represents a visitor that walks through a deserializer. pub trait Visitor { + /// The value produced by this visitor. type Value: Deserialize; + /// `visit_bool` deserializes a `bool` into a `Value`. fn visit_bool(&mut self, _v: bool) -> Result where E: Error, { Err(Error::type_mismatch(Type::Bool)) } + /// `visit_isize` deserializes a `isize` into a `Value`. fn visit_isize(&mut self, v: isize) -> Result where E: Error, { self.visit_i64(v as i64) } + /// `visit_i8` deserializes a `i8` into a `Value`. fn visit_i8(&mut self, v: i8) -> Result where E: Error, { self.visit_i64(v as i64) } + /// `visit_i16` deserializes a `i16` into a `Value`. fn visit_i16(&mut self, v: i16) -> Result where E: Error, { self.visit_i64(v as i64) } + /// `visit_i32` deserializes a `i32` into a `Value`. fn visit_i32(&mut self, v: i32) -> Result where E: Error, { self.visit_i64(v as i64) } + /// `visit_i64` deserializes a `i64` into a `Value`. fn visit_i64(&mut self, _v: i64) -> Result where E: Error, { Err(Error::type_mismatch(Type::I64)) } + /// `visit_usize` deserializes a `usize` into a `Value`. fn visit_usize(&mut self, v: usize) -> Result where E: Error, { self.visit_u64(v as u64) } + /// `visit_u8` deserializes a `u8` into a `Value`. fn visit_u8(&mut self, v: u8) -> Result where E: Error, { self.visit_u64(v as u64) } + /// `visit_u16` deserializes a `u16` into a `Value`. fn visit_u16(&mut self, v: u16) -> Result where E: Error, { self.visit_u64(v as u64) } + /// `visit_u32` deserializes a `u32` into a `Value`. fn visit_u32(&mut self, v: u32) -> Result where E: Error, { self.visit_u64(v as u64) } + /// `visit_u64` deserializes a `u64` into a `Value`. fn visit_u64(&mut self, _v: u64) -> Result where E: Error, { Err(Error::type_mismatch(Type::U64)) } + /// `visit_f32` deserializes a `f32` into a `Value`. fn visit_f32(&mut self, v: f32) -> Result where E: Error, { self.visit_f64(v as f64) } + /// `visit_f64` deserializes a `f64` into a `Value`. fn visit_f64(&mut self, _v: f64) -> Result where E: Error, { Err(Error::type_mismatch(Type::F64)) } + /// `visit_char` deserializes a `char` into a `Value`. #[inline] fn visit_char(&mut self, v: char) -> Result where E: Error, @@ -439,12 +516,14 @@ pub trait Visitor { self.visit_string(v.to_string()) } + /// `visit_str` deserializes a `&str` into a `Value`. fn visit_str(&mut self, _v: &str) -> Result where E: Error, { Err(Error::type_mismatch(Type::Str)) } + /// `visit_string` deserializes a `String` into a `Value`. #[inline] fn visit_string(&mut self, v: String) -> Result where E: Error, @@ -452,12 +531,14 @@ pub trait Visitor { self.visit_str(&v) } + /// `visit_unit` deserializes a `()` into a `Value`. fn visit_unit(&mut self) -> Result where E: Error, { Err(Error::type_mismatch(Type::Unit)) } + /// `visit_unit_struct` deserializes a unit struct into a `Value`. #[inline] fn visit_unit_struct(&mut self, _name: &'static str) -> Result where E: Error, @@ -465,42 +546,49 @@ pub trait Visitor { self.visit_unit() } + /// `visit_none` deserializes a none value into a `Value`. fn visit_none(&mut self) -> Result where E: Error, { Err(Error::type_mismatch(Type::Option)) } + /// `visit_some` deserializes a value into a `Value`. fn visit_some(&mut self, _deserializer: &mut D) -> Result where D: Deserializer, { Err(Error::type_mismatch(Type::Option)) } + /// `visit_newtype_struct` deserializes a value into a `Value`. fn visit_newtype_struct(&mut self, _deserializer: &mut D) -> Result where D: Deserializer, { Err(Error::type_mismatch(Type::NewtypeStruct)) } + /// `visit_bool` deserializes a `SeqVisitor` into a `Value`. fn visit_seq(&mut self, _visitor: V) -> Result where V: SeqVisitor, { Err(Error::type_mismatch(Type::Seq)) } + /// `visit_map` deserializes a `MapVisitor` into a `Value`. fn visit_map(&mut self, _visitor: V) -> Result where V: MapVisitor, { Err(Error::type_mismatch(Type::Map)) } + /// `visit_bytes` deserializes a `&[u8]` into a `Value`. fn visit_bytes(&mut self, _v: &[u8]) -> Result where E: Error, { Err(Error::type_mismatch(Type::Bytes)) } + /// `visit_byte_buf` deserializes a `Vec` into a `Value`. fn visit_byte_buf(&mut self, v: Vec) -> Result where E: Error, { @@ -510,14 +598,23 @@ pub trait Visitor { /////////////////////////////////////////////////////////////////////////////// +/// `SeqVisitor` visits each item in a sequence. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation, which deserializes +/// each item in a sequence. pub trait SeqVisitor { + /// The error type that can be returned if some error occurs during deserialization. type Error: Error; + /// This returns a `Ok(Some(value))` for the next value in the sequence, or `Ok(None)` if there + /// are no more remaining items. fn visit(&mut self) -> Result, Self::Error> where T: Deserialize; + /// This signals to the `SeqVisitor` that the `Visitor` does not expect any more items. fn end(&mut self) -> Result<(), Self::Error>; + /// Return the lower and upper bound of items remaining in the sequence. #[inline] fn size_hint(&self) -> (usize, Option) { (0, None) @@ -547,9 +644,15 @@ impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor { /////////////////////////////////////////////////////////////////////////////// +/// `MapVisitor` visits each item in a sequence. +/// +/// This is a trait that a `Deserializer` passes to a `Visitor` implementation. pub trait MapVisitor { + /// The error type that can be returned if some error occurs during deserialization. type Error: Error; + /// This returns a `Ok(Some((key, value)))` for the next (key-value) pair in the map, or + /// `Ok(None)` if there are no more remaining items. #[inline] fn visit(&mut self) -> Result, Self::Error> where K: Deserialize, @@ -564,19 +667,25 @@ pub trait MapVisitor { } } + /// This returns a `Ok(Some(key))` for the next key in the map, or `Ok(None)` if there are no + /// more remaining items. fn visit_key(&mut self) -> Result, Self::Error> where K: Deserialize; + /// This returns a `Ok(value)` for the next value in the map. fn visit_value(&mut self) -> Result where V: Deserialize; + /// This signals to the `MapVisitor` that the `Visitor` does not expect any more items. fn end(&mut self) -> Result<(), Self::Error>; + /// Return the lower and upper bound of items remaining in the sequence. #[inline] fn size_hint(&self) -> (usize, Option) { (0, None) } + /// Report that there fn missing_field(&mut self, field: &'static str) -> Result where V: Deserialize, { @@ -625,8 +734,10 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor { /// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the /// `Deserializer` in order to deserialize enums. pub trait EnumVisitor { + /// The value produced by this visitor. type Value; + /// Visit the specific variant with the `VariantVisitor`. fn visit(&mut self, visitor: V) -> Result where V: VariantVisitor; } @@ -636,6 +747,7 @@ pub trait EnumVisitor { /// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the /// `Deserialize` in order to deserialize a specific enum variant. pub trait VariantVisitor { + /// The error type that can be returned if some error occurs during deserialization. type Error: Error; /// `visit_variant` is called to identify which variant to deserialize. @@ -711,21 +823,3 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { (**self).visit_struct(fields, visitor) } } - -/////////////////////////////////////////////////////////////////////////////// - -pub trait EnumSeqVisitor { - type Value; - - fn visit(&mut self, visitor: V) -> Result - where V: SeqVisitor; -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait EnumMapVisitor { - type Value; - - fn visit(&mut self, visitor: V) -> Result - where V: MapVisitor; -} diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index af0716be..7e386619 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -1,3 +1,5 @@ +//! This module supports deserializing from primitives with the `ValueDeserializer` trait. + use std::collections::{ BTreeMap, BTreeSet, @@ -16,11 +18,19 @@ use bytes; /////////////////////////////////////////////////////////////////////////////// +/// This represents all the possible errors that can occur using the `ValueDeserializer`. #[derive(Clone, Debug, PartialEq)] pub enum Error { + /// The value had some syntatic error. SyntaxError, + + /// EOF while deserializing a value. EndOfStreamError, + + /// Unknown field in struct. UnknownFieldError(String), + + /// Struct is missing a field. MissingFieldError(&'static str), } @@ -33,9 +43,12 @@ impl de::Error for Error { /////////////////////////////////////////////////////////////////////////////// +/// This trait converts primitive types into a deserializer. pub trait ValueDeserializer { + /// The actual deserializer type. type Deserializer: de::Deserializer; + /// Convert this value into a deserializer. fn into_deserializer(self) -> Self::Deserializer; } @@ -72,6 +85,7 @@ impl de::Deserializer for UnitDeserializer { macro_rules! primitive_deserializer { ($ty:ty, $name:ident, $method:ident) => { + /// A helper deserializer that deserializes a number. pub struct $name(Option<$ty>); impl ValueDeserializer for $ty { @@ -212,12 +226,14 @@ impl<'a> de::VariantVisitor for StringDeserializer { /////////////////////////////////////////////////////////////////////////////// +/// A helper deserializer that deserializes a sequence. pub struct SeqDeserializer { iter: I, len: usize, } impl SeqDeserializer { + /// Construct a new `SeqDeserializer`. pub fn new(iter: I, len: usize) -> Self { SeqDeserializer { iter: iter, @@ -308,6 +324,7 @@ impl ValueDeserializer for HashSet /////////////////////////////////////////////////////////////////////////////// +/// A helper deserializer that deserializes a map. pub struct MapDeserializer where I: Iterator, K: ValueDeserializer, @@ -323,6 +340,7 @@ impl MapDeserializer K: ValueDeserializer, V: ValueDeserializer, { + /// Construct a new `MapDeserializer`. pub fn new(iter: I, len: usize) -> Self { MapDeserializer { iter: iter, @@ -429,6 +447,7 @@ impl<'a> ValueDeserializer for bytes::Bytes<'a> } } +/// A helper deserializer that deserializes a `&[u8]`. pub struct BytesDeserializer<'a> (Option<&'a [u8]>); impl<'a> de::Deserializer for BytesDeserializer<'a> { @@ -456,6 +475,7 @@ impl ValueDeserializer for bytes::ByteBuf } } +/// A helper deserializer that deserializes a `Vec`. pub struct ByteBufDeserializer(Option>); impl de::Deserializer for ByteBufDeserializer { diff --git a/serde/src/iter.rs b/serde/src/iter.rs index ec0bb134..24a6bf30 100644 --- a/serde/src/iter.rs +++ b/serde/src/iter.rs @@ -1,6 +1,9 @@ +//! Module that contains helper iterators. + use std::io; use std::iter::Peekable; +/// Iterator over a byte stream that tracks the current position's line and column. pub struct LineColIterator>> { iter: Iter, line: usize, @@ -8,6 +11,7 @@ pub struct LineColIterator>> { } impl>> LineColIterator { + /// Construct a new `LineColIterator`. pub fn new(iter: Iter) -> LineColIterator { LineColIterator { iter: iter, diff --git a/serde/src/lib.rs b/serde/src/lib.rs index d120f130..e6b8528f 100644 --- a/serde/src/lib.rs +++ b/serde/src/lib.rs @@ -5,9 +5,12 @@ //! 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. + #![doc(html_root_url="https://serde-rs.github.io/serde/serde")] #![cfg_attr(feature = "nightly", feature(collections, core, enumset, nonzero, step_trait, zero_one))] +#![deny(missing_docs)] + extern crate num; #[cfg(feature = "nightly")] diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 8a31b4af..63aea2ec 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -1,3 +1,5 @@ +//! Implementations for all of Rust's builtin types. + use std::borrow::Cow; use std::collections::{ BinaryHeap, @@ -117,6 +119,27 @@ impl SeqVisitor for Option where T: Serialize { /////////////////////////////////////////////////////////////////////////////// +/// A `serde::Visitor` for sequence iterators. +/// +/// # Examples +/// +/// ``` +/// use serde::{Serialize, Serializer}; +/// use serde::ser::impls::SeqIteratorVisitor; +/// +/// struct Seq(Vec); +/// +/// impl Serialize for Seq { +/// fn serialize(&self, ser: &mut S) -> Result<(), S::Error> +/// where S: Serializer, +/// { +/// ser.visit_seq(SeqIteratorVisitor::new( +/// self.0.iter(), +/// Some(self.0.len()), +/// )) +/// } +/// } +/// ``` pub struct SeqIteratorVisitor { iter: Iter, len: Option, @@ -125,6 +148,7 @@ pub struct SeqIteratorVisitor { impl SeqIteratorVisitor where Iter: Iterator { + /// Construct a new `SeqIteratorVisitor`. #[inline] pub fn new(iter: Iter, len: Option) -> SeqIteratorVisitor { SeqIteratorVisitor { @@ -332,12 +356,14 @@ macro_rules! tuple_impls { } )+) => { $( + /// A tuple visitor. pub struct $TupleVisitor<'a, $($T: 'a),+> { tuple: &'a ($($T,)+), state: u8, } impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> { + /// Construct a new, empty `TupleVisitor`. pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> { $TupleVisitor { tuple: tuple, @@ -489,6 +515,28 @@ tuple_impls! { /////////////////////////////////////////////////////////////////////////////// +/// A `serde::Visitor` for (key, value) map iterators. +/// +/// # Examples +/// +/// ``` +/// use std::collections::HashMap; +/// use serde::{Serialize, Serializer}; +/// use serde::ser::impls::MapIteratorVisitor; +/// +/// struct Map(HashMap); +/// +/// impl Serialize for Map { +/// fn serialize(&self, ser: &mut S) -> Result<(), S::Error> +/// where S: Serializer, +/// { +/// ser.visit_map(MapIteratorVisitor::new( +/// self.0.iter(), +/// Some(self.0.len()), +/// )) +/// } +/// } +/// ``` pub struct MapIteratorVisitor { iter: Iter, len: Option, @@ -497,6 +545,7 @@ pub struct MapIteratorVisitor { impl MapIteratorVisitor where Iter: Iterator { + /// Construct a new `MapIteratorVisitor`. #[inline] pub fn new(iter: Iter, len: Option) -> MapIteratorVisitor { MapIteratorVisitor { diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 3971495c..b07e654a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -4,14 +4,18 @@ pub mod impls; /////////////////////////////////////////////////////////////////////////////// +/// A trait that describes a type that can be serialized by a `Serializer`. pub trait Serialize { + /// Serializes this value into this serializer. fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer; } /////////////////////////////////////////////////////////////////////////////// +/// A trait that describes a type that can serialize a stream of values into the underlying format. pub trait Serializer { + /// The error type that can be returned if some error occurs during serialization. type Error; /// `visit_bool` serializes a `bool` value. @@ -110,13 +114,20 @@ pub trait Serializer { self.visit_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len()))) } + /// Serializes a `()` value. fn visit_unit(&mut self) -> Result<(), Self::Error>; + /// Serializes a unit struct value. + /// + /// By default, unit structs are serialized as a `()`. #[inline] fn visit_unit_struct(&mut self, _name: &'static str) -> Result<(), Self::Error> { self.visit_unit() } + /// Serializes a unit variant, otherwise known as a variant with no arguments. + /// + /// By default, unit variants are serialized as a `()`. #[inline] fn visit_unit_variant(&mut self, _name: &'static str, @@ -155,17 +166,27 @@ pub trait Serializer { Some(value)) } + /// Serializes a `None` value. fn visit_none(&mut self) -> Result<(), Self::Error>; + /// Serializes a `Some(...)` value. fn visit_some(&mut self, value: V) -> Result<(), Self::Error> where V: Serialize; + /// Serializes a sequence. + /// + /// Callees of this method need to construct a `SeqVisitor`, which iterates through each item + /// in the sequence. fn visit_seq(&mut self, visitor: V) -> Result<(), Self::Error> where V: SeqVisitor; + /// Serializes a sequence element. fn visit_seq_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize; + /// Serializes a tuple. + /// + /// By default this serializes a tuple as a sequence. #[inline] fn visit_tuple(&mut self, visitor: V) -> Result<(), Self::Error> where V: SeqVisitor, @@ -173,6 +194,9 @@ pub trait Serializer { self.visit_seq(visitor) } + /// Serializes a tuple element. + /// + /// By default, tuples are serialized as a sequence. #[inline] fn visit_tuple_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize @@ -180,6 +204,9 @@ pub trait Serializer { self.visit_seq_elt(value) } + /// Serializes a tuple struct. + /// + /// By default, tuple structs are serialized as a tuple. #[inline] fn visit_tuple_struct(&mut self, _name: &'static str, @@ -189,6 +216,9 @@ pub trait Serializer { self.visit_tuple(visitor) } + /// Serializes a tuple struct element. + /// + /// By default, tuple struct elements are serialized as a tuple element. #[inline] fn visit_tuple_struct_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize @@ -196,6 +226,9 @@ pub trait Serializer { self.visit_tuple_elt(value) } + /// Serializes a tuple variant. + /// + /// By default, tuple variants are serialized as a tuple struct. #[inline] fn visit_tuple_variant(&mut self, _name: &'static str, @@ -207,6 +240,9 @@ pub trait Serializer { self.visit_tuple_struct(variant, visitor) } + /// Serializes a tuple element. + /// + /// By default, tuples are serialized as a sequence. #[inline] fn visit_tuple_variant_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize @@ -214,13 +250,21 @@ pub trait Serializer { self.visit_tuple_struct_elt(value) } + /// Serializes a map. + /// + /// Callees of this method need to construct a `MapVisitor`, which iterates through each item + /// in the map. fn visit_map(&mut self, visitor: V) -> Result<(), Self::Error> where V: MapVisitor; + /// Serializes a map element (key-value pair). fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize; + /// Serializes a struct. + /// + /// By default, structs are serialized as a map with the field name as the key. #[inline] fn visit_struct(&mut self, _name: &'static str, @@ -230,6 +274,9 @@ pub trait Serializer { self.visit_map(visitor) } + /// Serializes an element of a struct. + /// + /// By default, struct elements are serialized as a map element with the field name as the key. #[inline] fn visit_struct_elt(&mut self, key: &'static str, @@ -239,6 +286,9 @@ pub trait Serializer { self.visit_map_elt(key, value) } + /// Serializes a struct variant. + /// + /// By default, struct variants are serialized as a struct. #[inline] fn visit_struct_variant(&mut self, _name: &'static str, @@ -250,6 +300,9 @@ pub trait Serializer { self.visit_struct(variant, visitor) } + /// Serializes an element of a struct variant. + /// + /// By default, struct variant elements are serialized as a struct element. #[inline] fn visit_struct_variant_elt(&mut self, key: &'static str, @@ -268,7 +321,12 @@ pub trait Serializer { } } +/// A trait that is used by a `Serialize` to iterate through a sequence. pub trait SeqVisitor { + /// Serializes a sequence item in the serializer. + /// + /// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when + /// complete. fn visit(&mut self, serializer: &mut S) -> Result, S::Error> where S: Serializer; @@ -279,7 +337,12 @@ pub trait SeqVisitor { } } +/// A trait that is used by a `Serializer` to iterate through a map. pub trait MapVisitor { + /// Serializes a map item in the serializer. + /// + /// This returns `Ok(Some(()))` when there are more items to serialize, or `Ok(None)` when + /// complete. fn visit(&mut self, serializer: &mut S) -> Result, S::Error> where S: Serializer;