diff --git a/src/ser.rs b/src/ser/impls.rs similarity index 69% rename from src/ser.rs rename to src/ser/impls.rs index 26fc91cf..babfa5ea 100644 --- a/src/ser.rs +++ b/src/ser/impls.rs @@ -3,188 +3,14 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecMap}; use std::hash::Hash; use std::path; use std::rc::Rc; -use std::str; use std::sync::Arc; -/////////////////////////////////////////////////////////////////////////////// - -pub trait Serialize { - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: Serializer; -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait Serializer { - type Error; - - fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error>; - - #[inline] - fn visit_isize(&mut self, v: isize) -> Result<(), Self::Error> { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i8(&mut self, v: i8) -> Result<(), Self::Error> { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i16(&mut self, v: i16) -> Result<(), Self::Error> { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i32(&mut self, v: i32) -> Result<(), Self::Error> { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error>; - - #[inline] - fn visit_usize(&mut self, v: usize) -> Result<(), Self::Error> { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u8(&mut self, v: u8) -> Result<(), Self::Error> { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u16(&mut self, v: u16) -> Result<(), Self::Error> { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u32(&mut self, v: u32) -> Result<(), Self::Error> { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error>; - - #[inline] - fn visit_f32(&mut self, v: f32) -> Result<(), Self::Error> { - self.visit_f64(v as f64) - } - - fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error>; - - /// `visit_char` serializes a character. By default it serializes it as a `&str` containing a - /// single character. - #[inline] - fn visit_char(&mut self, v: char) -> Result<(), Self::Error> { - // The unwraps in here should be safe. - let mut s = &mut [0; 4]; - let len = v.encode_utf8(s).unwrap(); - self.visit_str(str::from_utf8(&s[..len]).unwrap()) - } - - /// `visit_str` serializes a `&str`. - fn visit_str(&mut self, value: &str) -> Result<(), Self::Error>; - - /// `visit_bytes` is a hook that enables those serialization formats that support serializing - /// byte slices separately from generic arrays. By default it serializes as a regular array. - #[inline] - fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> { - self.visit_seq(SeqIteratorVisitor::new(value.iter(), Some(value.len()))) - } - - fn visit_unit(&mut self) -> Result<(), Self::Error>; - - #[inline] - fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> { - self.visit_unit() - } - - #[inline] - fn visit_enum_unit(&mut self, - _name: &str, - _variant: &str) -> Result<(), Self::Error> { - self.visit_unit() - } - - fn visit_none(&mut self) -> Result<(), Self::Error>; - - fn visit_some(&mut self, value: V) -> Result<(), Self::Error> - where V: Serialize; - - fn visit_seq(&mut self, visitor: V) -> Result<(), Self::Error> - where V: SeqVisitor; - - #[inline] - fn visit_named_seq(&mut self, - _name: &'static str, - visitor: V) -> Result<(), Self::Error> - where V: SeqVisitor, - { - self.visit_seq(visitor) - } - - #[inline] - fn visit_enum_seq(&mut self, - _name: &'static str, - _variant: &'static str, - visitor: V) -> Result<(), Self::Error> - where V: SeqVisitor, - { - self.visit_seq(visitor) - } - - fn visit_seq_elt(&mut self, value: T) -> Result<(), Self::Error> - where T: Serialize; - - fn visit_map(&mut self, visitor: V) -> Result<(), Self::Error> - where V: MapVisitor; - - #[inline] - fn visit_named_map(&mut self, - _name: &'static str, - visitor: V) -> Result<(), Self::Error> - where V: MapVisitor, - { - self.visit_map(visitor) - } - - #[inline] - fn visit_enum_map(&mut self, - _name: &'static str, - _variant: &'static str, - visitor: V) -> Result<(), Self::Error> - where V: MapVisitor, - { - self.visit_map(visitor) - } - - fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> - where K: Serialize, - V: Serialize; -} - -pub trait SeqVisitor { - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> - where S: Serializer; - - /// Return the length of the sequence if known. - #[inline] - fn len(&self) -> Option { - None - } -} - -pub trait MapVisitor { - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> - where S: Serializer; - - /// Return the length of the map if known. - #[inline] - fn len(&self) -> Option { - None - } -} +use super::{ + Serialize, + Serializer, + SeqVisitor, + MapVisitor, +}; /////////////////////////////////////////////////////////////////////////////// diff --git a/src/ser/mod.rs b/src/ser/mod.rs new file mode 100644 index 00000000..3c0e79eb --- /dev/null +++ b/src/ser/mod.rs @@ -0,0 +1,183 @@ +use std::str; + +pub mod impls; + +/////////////////////////////////////////////////////////////////////////////// + +pub trait Serialize { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer; +} + +/////////////////////////////////////////////////////////////////////////////// + +pub trait Serializer { + type Error; + + fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error>; + + #[inline] + fn visit_isize(&mut self, v: isize) -> Result<(), Self::Error> { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i8(&mut self, v: i8) -> Result<(), Self::Error> { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i16(&mut self, v: i16) -> Result<(), Self::Error> { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i32(&mut self, v: i32) -> Result<(), Self::Error> { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error>; + + #[inline] + fn visit_usize(&mut self, v: usize) -> Result<(), Self::Error> { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u8(&mut self, v: u8) -> Result<(), Self::Error> { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u16(&mut self, v: u16) -> Result<(), Self::Error> { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u32(&mut self, v: u32) -> Result<(), Self::Error> { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error>; + + #[inline] + fn visit_f32(&mut self, v: f32) -> Result<(), Self::Error> { + self.visit_f64(v as f64) + } + + fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error>; + + /// `visit_char` serializes a character. By default it serializes it as a `&str` containing a + /// single character. + #[inline] + fn visit_char(&mut self, v: char) -> Result<(), Self::Error> { + // The unwraps in here should be safe. + let mut s = &mut [0; 4]; + let len = v.encode_utf8(s).unwrap(); + self.visit_str(str::from_utf8(&s[..len]).unwrap()) + } + + /// `visit_str` serializes a `&str`. + fn visit_str(&mut self, value: &str) -> Result<(), Self::Error>; + + /// `visit_bytes` is a hook that enables those serialization formats that support serializing + /// byte slices separately from generic arrays. By default it serializes as a regular array. + #[inline] + fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> { + self.visit_seq(impls::SeqIteratorVisitor::new(value.iter(), Some(value.len()))) + } + + fn visit_unit(&mut self) -> Result<(), Self::Error>; + + #[inline] + fn visit_named_unit(&mut self, _name: &str) -> Result<(), Self::Error> { + self.visit_unit() + } + + #[inline] + fn visit_enum_unit(&mut self, + _name: &str, + _variant: &str) -> Result<(), Self::Error> { + self.visit_unit() + } + + fn visit_none(&mut self) -> Result<(), Self::Error>; + + fn visit_some(&mut self, value: V) -> Result<(), Self::Error> + where V: Serialize; + + fn visit_seq(&mut self, visitor: V) -> Result<(), Self::Error> + where V: SeqVisitor; + + #[inline] + fn visit_named_seq(&mut self, + _name: &'static str, + visitor: V) -> Result<(), Self::Error> + where V: SeqVisitor, + { + self.visit_seq(visitor) + } + + #[inline] + fn visit_enum_seq(&mut self, + _name: &'static str, + _variant: &'static str, + visitor: V) -> Result<(), Self::Error> + where V: SeqVisitor, + { + self.visit_seq(visitor) + } + + fn visit_seq_elt(&mut self, value: T) -> Result<(), Self::Error> + where T: Serialize; + + fn visit_map(&mut self, visitor: V) -> Result<(), Self::Error> + where V: MapVisitor; + + #[inline] + fn visit_named_map(&mut self, + _name: &'static str, + visitor: V) -> Result<(), Self::Error> + where V: MapVisitor, + { + self.visit_map(visitor) + } + + #[inline] + fn visit_enum_map(&mut self, + _name: &'static str, + _variant: &'static str, + visitor: V) -> Result<(), Self::Error> + where V: MapVisitor, + { + self.visit_map(visitor) + } + + fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> + where K: Serialize, + V: Serialize; +} + +pub trait SeqVisitor { + fn visit(&mut self, serializer: &mut S) -> Result, S::Error> + where S: Serializer; + + /// Return the length of the sequence if known. + #[inline] + fn len(&self) -> Option { + None + } +} + +pub trait MapVisitor { + fn visit(&mut self, serializer: &mut S) -> Result, S::Error> + where S: Serializer; + + /// Return the length of the map if known. + #[inline] + fn len(&self) -> Option { + None + } +}