diff options
Diffstat (limited to 'src/ser/mod.rs')
-rw-r--r-- | src/ser/mod.rs | 539 |
1 files changed, 277 insertions, 262 deletions
diff --git a/src/ser/mod.rs b/src/ser/mod.rs index 00c0540..400846f 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -2,12 +2,14 @@ mod key; mod pair; +mod part; mod value; use serde::ser; use std::borrow::Cow; use std::error; use std::fmt; +use std::marker::PhantomData; use std::str; use url::form_urlencoded::Serializer as UrlEncodedSerializer; use url::form_urlencoded::Target as UrlEncodedTarget; @@ -27,12 +29,9 @@ use url::form_urlencoded::Target as UrlEncodedTarget; /// Ok("bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter".to_owned())); /// ``` pub fn to_string<T: ser::Serialize>(input: &T) -> Result<String, Error> { - let mut output = String::new(); - { - let mut urlencoder = UrlEncodedSerializer::new(&mut output); - input.serialize(&mut Serializer::new(&mut urlencoder))?; - } - Ok(output) + let mut urlencoder = UrlEncodedSerializer::new("".to_owned()); + input.serialize(Serializer::new(&mut urlencoder))?; + Ok(urlencoder.finish()) } /// A serializer for the `application/x-www-form-urlencoded` format. @@ -44,13 +43,13 @@ pub fn to_string<T: ser::Serialize>(input: &T) -> Result<String, Error> { /// unit structs and unit variants. /// /// * Newtype structs defer to their inner values. -pub struct Serializer<'output, T: 'output + UrlEncodedTarget> { - urlencoder: &'output mut UrlEncodedSerializer<T>, +pub struct Serializer<'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<Target>, } -impl<'output, T: 'output + UrlEncodedTarget> Serializer<'output, T> { +impl<'output, Target: 'output + UrlEncodedTarget> Serializer<'output, Target> { /// Returns a new `Serializer`. - pub fn new(urlencoder: &'output mut UrlEncodedSerializer<T>) -> Self { + pub fn new(urlencoder: &'output mut UrlEncodedSerializer<Target>) -> Self { Serializer { urlencoder: urlencoder } } } @@ -59,15 +58,13 @@ impl<'output, T: 'output + UrlEncodedTarget> Serializer<'output, T> { #[derive(Clone, Debug, PartialEq, Eq)] pub enum Error { Custom(Cow<'static, str>), - InvalidValue(Cow<'static, str>), Utf8(str::Utf8Error), } impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::Custom(ref msg) => msg.fmt(f), - Error::InvalidValue(ref msg) => write!(f, "invalid value: {}", msg), Error::Utf8(ref err) => write!(f, "invalid UTF-8: {}", err), } } @@ -77,7 +74,6 @@ impl error::Error for Error { fn description(&self) -> &str { match *self { Error::Custom(ref msg) => msg, - Error::InvalidValue(ref msg) => msg, Error::Utf8(ref err) => error::Error::description(err), } } @@ -85,413 +81,432 @@ impl error::Error for Error { /// The lower-level cause of this error, in the case of a `Utf8` error. fn cause(&self) -> Option<&error::Error> { match *self { - Error::Custom(_) | - Error::InvalidValue(_) => None, + Error::Custom(_) => None, Error::Utf8(ref err) => Some(err), } } } impl ser::Error for Error { - fn custom<T: Into<String>>(msg: T) -> Self { - Error::Custom(msg.into().into()) - } - - fn invalid_value(msg: &str) -> Self { - Error::InvalidValue(String::from(msg).into()) + fn custom<T: fmt::Display>(msg: T) -> Self { + Error::Custom(format!("{}", msg).into()) } } -/// State used when serializing sequences. -pub struct SeqState { - _state: (), +/// Sequence serializer. +pub struct SeqSerializer<'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<Target>, } -/// State used when serializing tuples. -pub struct TupleState { - _state: (), +/// Tuple serializer. +/// +/// Never instantiated, tuples are not supported at top-level. +pub struct TupleSerializer<'output, T: 'output + UrlEncodedTarget> { + _marker: PhantomData<&'output T>, } -/// State used when serializing tuple structs. -pub struct TupleStructState { - _state: (), +/// Tuple struct serializer. +/// +/// Never instantiated, tuple structs are not supported. +pub struct TupleStructSerializer<'output, T: 'output + UrlEncodedTarget> { + _marker: PhantomData<&'output T>, } -/// State used when serializing tuple variants. -pub struct TupleVariantState { - _state: (), +/// Tuple variant serializer. +/// +/// Never instantiated, tuple variants are not supported. +pub struct TupleVariantSerializer<'output, T: 'output + UrlEncodedTarget> { + _marker: PhantomData<&'output T>, } -/// State used when serializing maps. -pub struct MapState { +/// Map serializer. +pub struct MapSerializer<'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<Target>, key: Option<Cow<'static, str>>, } -/// State used when serializing structs. -pub struct StructState { - _state: (), +/// Struct serializer. +pub struct StructSerializer<'output, Target: 'output + UrlEncodedTarget> { + urlencoder: &'output mut UrlEncodedSerializer<Target>, } -/// State used when serializing struct variants. -pub struct StructVariantState { - _state: (), +/// Struct variant serializer. +/// +/// Never instantiated, struct variants are not supported. +pub struct StructVariantSerializer<'output, T: 'output + UrlEncodedTarget> { + _marker: PhantomData<&'output T>, } impl<'output, Target> ser::Serializer for Serializer<'output, Target> where Target: 'output + UrlEncodedTarget, { + type Ok = &'output mut UrlEncodedSerializer<Target>; type Error = Error; - - /// State used when serializing sequences. - type SeqState = SeqState; - - /// State used when serializing tuples. - type TupleState = TupleState; - - /// State used when serializing tuple structs. - type TupleStructState = TupleStructState; - - /// State used when serializing tuple variants. - type TupleVariantState = TupleVariantState; - - /// State used when serializing maps. - type MapState = MapState; - - /// State used when serializing structs. - type StructState = StructState; - - /// State used when serializing struct variants. - type StructVariantState = StructVariantState; + type SerializeSeq = SeqSerializer<'output, Target>; + type SerializeTuple = TupleSerializer<'output, Target>; + type SerializeTupleStruct = TupleStructSerializer<'output, Target>; + type SerializeTupleVariant = TupleVariantSerializer<'output, Target>; + type SerializeMap = MapSerializer<'output, Target>; + type SerializeStruct = StructSerializer<'output, Target>; + type SerializeStructVariant = StructVariantSerializer<'output, Target>; /// Returns an error. - fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> { + fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_isize(&mut self, _v: isize) -> Result<(), Error> { + fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_i8(&mut self, _v: i8) -> Result<(), Error> { + fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_i16(&mut self, _v: i16) -> Result<(), Error> { + fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_i32(&mut self, _v: i32) -> Result<(), Error> { + fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> { + fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_usize(&mut self, _v: usize) -> Result<(), Error> { + fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_u8(&mut self, _v: u8) -> Result<(), Error> { + fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_u16(&mut self, _v: u16) -> Result<(), Error> { + fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_u32(&mut self, _v: u32) -> Result<(), Error> { + fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_u64(&mut self, _v: u64) -> Result<(), Error> { + fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_f32(&mut self, _v: f32) -> Result<(), Error> { + fn serialize_char(self, _v: char) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_f64(&mut self, _v: f64) -> Result<(), Error> { + fn serialize_str(self, _value: &str) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_char(&mut self, _v: char) -> Result<(), Error> { + fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_str(&mut self, _value: &str) -> Result<(), Error> { + fn serialize_unit(self) -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_bytes(&mut self, _value: &[u8]) -> Result<(), Error> { - Err(Error::top_level()) - } - - /// Returns an error. - fn serialize_unit(&mut self) -> Result<(), Error> { - Err(Error::top_level()) - } - - /// Returns an error. - fn serialize_unit_struct(&mut self, + fn serialize_unit_struct(self, _name: &'static str) - -> Result<(), Error> { + -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_unit_variant(&mut self, + fn serialize_unit_variant(self, _name: &'static str, _variant_index: usize, _variant: &'static str) - -> Result<(), Error> { + -> Result<Self::Ok, Error> { Err(Error::top_level()) } /// Serializes the inner value, ignoring the newtype name. - fn serialize_newtype_struct<T>(&mut self, - _name: &'static str, - value: T) - -> Result<(), Error> - where T: ser::Serialize, - { + fn serialize_newtype_struct<T: ?Sized + ser::Serialize> + (self, + _name: &'static str, + value: &T) + -> Result<Self::Ok, Error> { value.serialize(self) } /// Returns an error. - fn serialize_newtype_variant<T>(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - _value: T) - -> Result<(), Error> - where T: ser::Serialize, - { + fn serialize_newtype_variant<T: ?Sized + ser::Serialize> + (self, + _name: &'static str, + _variant_index: usize, + _variant: &'static str, + _value: &T) + -> Result<Self::Ok, Error> { Err(Error::top_level()) } - /// Returns an error. - fn serialize_none(&mut self) -> Result<(), Error> { - Ok(()) + /// Returns `Ok`. + fn serialize_none(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) } - /// Returns an error. - fn serialize_some<T>(&mut self, value: T) -> Result<(), Error> - where T: ser::Serialize, - { + /// Serializes the given value. + fn serialize_some<T: ?Sized + ser::Serialize> + (self, + value: &T) + -> Result<Self::Ok, Error> { value.serialize(self) } - /// Begins to serialize a sequence, given length (if any) is ignored. - fn serialize_seq(&mut self, + /// Serialize a sequence, given length (if any) is ignored. + fn serialize_seq(self, _len: Option<usize>) - -> Result<SeqState, Error> { - Ok(SeqState { _state: () }) + -> Result<Self::SerializeSeq, Error> { + Ok(SeqSerializer { urlencoder: self.urlencoder }) } - /// Serializes a sequence element. - fn serialize_seq_elt<T>(&mut self, - _state: &mut SeqState, - value: T) - -> Result<(), Error> - where T: ser::Serialize, - { - value.serialize(&mut pair::PairSerializer::new(self.urlencoder)) - } - - /// Finishes serializing a sequence. - fn serialize_seq_end(&mut self, _state: SeqState) -> Result<(), Error> { - Ok(()) - } - - /// Begins to serialize a sequence, given length is ignored. - fn serialize_seq_fixed_size(&mut self, - _length: usize) - -> Result<SeqState, Error> { - Ok(SeqState { _state: () }) + /// Serializes a sequence, given length is ignored. + fn serialize_seq_fixed_size(self, + _len: usize) + -> Result<Self::SerializeSeq, Error> { + Ok(SeqSerializer { urlencoder: self.urlencoder }) } /// Returns an error. - fn serialize_tuple(&mut self, _len: usize) -> Result<TupleState, Error> { + fn serialize_tuple(self, + _len: usize) + -> Result<Self::SerializeTuple, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_tuple_elt<T>(&mut self, - _state: &mut TupleState, - _value: T) - -> Result<(), Error> - where T: ser::Serialize, - { + fn serialize_tuple_struct(self, + _name: &'static str, + _len: usize) + -> Result<Self::SerializeTupleStruct, Error> { Err(Error::top_level()) } /// Returns an error. - fn serialize_tuple_end(&mut self, _state: TupleState) -> Result<(), Error> { + fn serialize_tuple_variant + (self, + _name: &'static str, + _variant_index: usize, + _variant: &'static str, + _len: usize) + -> Result<Self::SerializeTupleVariant, Error> { Err(Error::top_level()) } - /// Returns an error. - fn serialize_tuple_struct(&mut self, - _name: &'static str, - _len: usize) - -> Result<TupleStructState, Error> { - Err(Error::top_level()) + /// Serializes a map, given length is ignored. + fn serialize_map(self, + _len: Option<usize>) + -> Result<Self::SerializeMap, Error> { + Ok(MapSerializer { + urlencoder: self.urlencoder, + key: None, + }) } - /// Returns an error. - fn serialize_tuple_struct_elt<T>(&mut self, - _state: &mut TupleStructState, - _value: T) - -> Result<(), Error> - where T: ser::Serialize, - { - Err(Error::top_level()) + /// Serializes a struct, given length is ignored. + fn serialize_struct(self, + _name: &'static str, + _len: usize) + -> Result<Self::SerializeStruct, Error> { + Ok(StructSerializer { urlencoder: self.urlencoder }) } /// Returns an error. - fn serialize_tuple_struct_end(&mut self, - _state: TupleStructState) - -> Result<(), Error> { + fn serialize_struct_variant + (self, + _name: &'static str, + _variant_index: usize, + _variant: &'static str, + _len: usize) + -> Result<Self::SerializeStructVariant, Error> { Err(Error::top_level()) } +} - /// Returns an error. - fn serialize_tuple_variant(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - _len: usize) - -> Result<TupleVariantState, Error> { - Err(Error::top_level()) +impl<'output, Target> ser::SerializeSeq for SeqSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_element<T: ?Sized + ser::Serialize>(&mut self, + value: &T) + -> Result<(), Error> { + value.serialize(pair::PairSerializer::new(self.urlencoder)) } - /// Returns an error. - fn serialize_tuple_variant_elt<T>(&mut self, - _state: &mut TupleVariantState, - _value: T) - -> Result<(), Error> - where T: ser::Serialize, - { - Err(Error::top_level()) + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) } +} - /// Returns an error. - fn serialize_tuple_variant_end(&mut self, - _state: TupleVariantState) - -> Result<(), Error> { - Err(Error::top_level()) +impl<'output, Target> ser::SerializeTuple for TupleSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_element<T: ?Sized + ser::Serialize>(&mut self, + _value: &T) + -> Result<(), Error> { + unreachable!() } - /// Begins to serialize a map, given length (if any) is ignored. - fn serialize_map(&mut self, - _len: Option<usize>) - -> Result<MapState, Error> { - Ok(MapState { key: None }) - } - - /// Serializes a map key. - fn serialize_map_key<T>(&mut self, - state: &mut MapState, - key: T) - -> Result<(), Error> - where T: ser::Serialize, - { - key.serialize(&mut key::MapKeySerializer::new(&mut state.key)) - } - - /// Serializes a map value. - fn serialize_map_value<T>(&mut self, - state: &mut MapState, - value: T) - -> Result<(), Error> - where T: ser::Serialize, - { - let mut value_serializer = - value::ValueSerializer::new(&mut state.key, self.urlencoder)?; - value.serialize(&mut value_serializer) - } - - /// Finishes serializing a map. - fn serialize_map_end(&mut self, _state: MapState) -> Result<(), Error> { + fn end(self) -> Result<Self::Ok, Error> { + unreachable!() + } +} + +impl<'output, Target> ser::SerializeTupleStruct + for TupleStructSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, + _value: &T) + -> Result<(), Error> { + unreachable!() + } + + fn end(self) -> Result<Self::Ok, Error> { + unreachable!() + } +} + +impl<'output, Target> ser::SerializeTupleVariant + for TupleVariantSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, + _value: &T) + -> Result<(), Error> { + unreachable!() + } + + fn end(self) -> Result<Self::Ok, Error> { + unreachable!() + } +} + +impl<'output, Target> ser::SerializeMap for MapSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_entry<K: ?Sized + ser::Serialize, V: ?Sized + ser::Serialize> + (&mut self, + key: &K, + value: &V) + -> Result<(), Error> { + let key_sink = key::KeySink::new(|key| { + let value_sink = value::ValueSink::new(self.urlencoder, &key); + value.serialize(part::PartSerializer::new(value_sink))?; + self.key = None; + Ok(()) + }); + let entry_serializer = part::PartSerializer::new(key_sink); + key.serialize(entry_serializer) + } + + fn serialize_key<T: ?Sized + ser::Serialize>(&mut self, + key: &T) + -> Result<(), Error> { + let key_sink = key::KeySink::new(|key| Ok(key.into())); + let key_serializer = part::PartSerializer::new(key_sink); + self.key = Some(key.serialize(key_serializer)?); Ok(()) } - /// Begins to serialize a struct, given length is ignored. - fn serialize_struct(&mut self, - _name: &'static str, - _len: usize) - -> Result<StructState, Error> { - Ok(StructState { _state: () }) - } - - /// Serializes a struct element. - fn serialize_struct_elt<T>(&mut self, - _state: &mut StructState, - key: &'static str, - value: T) - -> Result<(), Error> - where T: ser::Serialize, - { - let mut key = Some(key.into()); - let mut value_serializer = - value::ValueSerializer::new(&mut key, self.urlencoder).unwrap(); - value.serialize(&mut value_serializer) - } - - /// Finishes serializing a struct. - fn serialize_struct_end(&mut self, - _state: StructState) - -> Result<(), Error> { + fn serialize_value<T: ?Sized + ser::Serialize>(&mut self, + value: &T) + -> Result<(), Error> { + { + let key = self.key.as_ref().ok_or_else(|| Error::no_key())?; + let value_sink = value::ValueSink::new(self.urlencoder, &key); + value.serialize(part::PartSerializer::new(value_sink))?; + } + self.key = None; Ok(()) } - /// Returns an error. - fn serialize_struct_variant(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - _len: usize) - -> Result<StructVariantState, Error> { - Err(Error::top_level()) + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) } +} - /// Returns an error. - fn serialize_struct_variant_elt<T>(&mut self, - _state: &mut StructVariantState, - _key: &'static str, - _value: T) - -> Result<(), Error> { - Err(Error::top_level()) +impl<'output, Target> ser::SerializeStruct for StructSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, + key: &'static str, + value: &T) + -> Result<(), Error> { + let value_sink = value::ValueSink::new(self.urlencoder, key); + value.serialize(part::PartSerializer::new(value_sink)) } - /// Returns an error. - fn serialize_struct_variant_end(&mut self, - _state: StructVariantState) - -> Result<(), Error> { - Err(Error::top_level()) + fn end(self) -> Result<Self::Ok, Error> { + Ok(self.urlencoder) + } +} + +impl<'output, Target> ser::SerializeStructVariant + for StructVariantSerializer<'output, Target> + where Target: 'output + UrlEncodedTarget, +{ + type Ok = &'output mut UrlEncodedSerializer<Target>; + type Error = Error; + + fn serialize_field<T: ?Sized + ser::Serialize>(&mut self, + _key: &'static str, + _value: &T) + -> Result<(), Error> { + unreachable!() + } + + fn end(self) -> Result<Self::Ok, Error> { + unreachable!() } } impl Error { fn top_level() -> Self { - Error::Custom("top-level serializer supports only maps and structs" - .into()) + let msg = "top-level serializer supports only maps and structs"; + Error::Custom(msg.into()) + } + + fn no_key() -> Self { + let msg = "tried to serialize a value before serializing key"; + Error::Custom(msg.into()) } } |