From 23abb48e9b01d46dfefb278ae821de701586f79c Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar <erick.tryzelaar@gmail.com> Date: Sun, 22 Jun 2014 21:54:58 -0400 Subject: [PATCH] Simplify the Serializable typarams This closes #14302 --- bench_log.rs | 63 +++++++++++++++++------- json.rs | 83 +++++++++++++++----------------- ser.rs | 133 +++++++++++++++++++++++++++++---------------------- 3 files changed, 159 insertions(+), 120 deletions(-) diff --git a/bench_log.rs b/bench_log.rs index c99cb84d..bf13ec62 100644 --- a/bench_log.rs +++ b/bench_log.rs @@ -24,9 +24,12 @@ struct Http { request_uri: String, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Http { +impl ser::Serializable for Http { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Http", 9)); try!(s.serialize_struct_sep("protocol")); @@ -67,9 +70,12 @@ enum HttpProtocol { HTTP11, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for HttpProtocol { +impl ser::Serializable for HttpProtocol { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -89,9 +95,12 @@ enum HttpMethod { PATCH, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for HttpMethod { +impl ser::Serializable for HttpMethod { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -104,9 +113,12 @@ enum CacheStatus { Hit, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for CacheStatus { +impl ser::Serializable for CacheStatus { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -119,9 +131,12 @@ struct Origin { protocol: OriginProtocol, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Origin { +impl ser::Serializable for Origin { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Http", 4)); try!(s.serialize_struct_sep("ip")); @@ -147,9 +162,12 @@ enum OriginProtocol { HTTPS, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for OriginProtocol { +impl ser::Serializable for OriginProtocol { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -163,9 +181,12 @@ enum ZonePlan { ENT, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for ZonePlan { +impl ser::Serializable for ZonePlan { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -430,9 +451,12 @@ enum Country { ZW, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Country { +impl ser::Serializable for Country { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_uint(*self as uint) } } @@ -453,9 +477,12 @@ struct Log { ray_id: String, } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Log { +impl ser::Serializable for Log { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Log", 12)); try!(s.serialize_struct_sep("timestamp")); diff --git a/json.rs b/json.rs index 64f9388b..1447c201 100644 --- a/json.rs +++ b/json.rs @@ -233,7 +233,6 @@ use std::collections::treemap; use std::fmt; use std::io::MemWriter; use std::io; -use std::mem::transmute; use std::num; use std::str::ScalarValue; use std::str; @@ -419,9 +418,12 @@ impl fmt::Show for Json { } } -impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Json { +impl ser::Serializable for Json { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { match *self { Null => { ().serialize(s) @@ -780,26 +782,17 @@ impl<'a> Serializer<'a> { } /// Encode the specified struct into a json [u8] - pub fn buf_encode< - 'a, - T: ser::Serializable<Serializer<'a>, io::IoError> - >(value: &T) -> Vec<u8> { - //Serialize the object in a string using a writer + pub fn buf_encode<T: ser::Serializable>(value: &T) -> Vec<u8> { let mut wr = MemWriter::new(); - // FIXME(14302) remove the transmute and unsafe block. - unsafe { + { let mut serializer = Serializer::new(&mut wr); - // MemWriter never Errs - let _ = value.serialize(transmute(&mut serializer)); + value.serialize(&mut serializer).unwrap(); } wr.unwrap() } /// Encode the specified struct into a json str - pub fn str_encode< - 'a, - T: ser::Serializable<Serializer<'a>, io::IoError> - >(value: &T) -> Result<String, Vec<u8>> { + pub fn str_encode<T: ser::Serializable>(value: &T) -> Result<String, Vec<u8>> { let buf = Serializer::buf_encode(value); String::from_utf8(buf) } @@ -958,7 +951,7 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> { #[inline] fn serialize_option< - T: Serializable<Serializer<'a>, io::IoError> + T: Serializable >(&mut self, v: &Option<T>) -> Result<(), io::IoError> { match *v { Some(ref v) => { @@ -972,7 +965,7 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> { #[inline] fn serialize_seq< - T: Serializable<Serializer<'a>, io::IoError>, + T: Serializable, Iter: Iterator<T> >(&mut self, mut iter: Iter) -> Result<(), io::IoError> { try!(self.wr.write_str("[")); @@ -991,8 +984,8 @@ impl<'a> ser::Serializer<io::IoError> for Serializer<'a> { #[inline] fn serialize_map< - K: Serializable<Serializer<'a>, io::IoError>, - V: Serializable<Serializer<'a>, io::IoError>, + K: Serializable, + V: Serializable, Iter: Iterator<(K, V)> >(&mut self, mut iter: Iter) -> Result<(), io::IoError> { try!(self.wr.write_str("{")); @@ -1031,23 +1024,17 @@ impl<'a> PrettySerializer<'a> { } /// Encode the specified struct into a json [u8] - pub fn buf_encode< - T: ser::Serializable<PrettySerializer<'a>, io::IoError> - >(value: &T) -> Vec<u8> { + pub fn buf_encode<T: ser::Serializable>(value: &T) -> Vec<u8> { let mut wr = MemWriter::new(); - // FIXME(14302) remove the transmute and unsafe block. - unsafe { + { let mut serializer = PrettySerializer::new(&mut wr); - // MemWriter never Errs - let _ = value.serialize(transmute(&mut serializer)); + value.serialize(&mut serializer).unwrap(); } wr.unwrap() } /// Encode the specified struct into a json str - pub fn str_encode< - T: ser::Serializable<PrettySerializer<'a>, io::IoError> - >(value: &T) -> Result<String, Vec<u8>> { + pub fn str_encode<T: ser::Serializable>(value: &T) -> Result<String, Vec<u8>> { let buf = PrettySerializer::buf_encode(value); String::from_utf8(buf) } @@ -1218,7 +1205,7 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> { #[inline] fn serialize_option< - T: Serializable<PrettySerializer<'a>, io::IoError> + T: Serializable >(&mut self, v: &Option<T>) -> Result<(), io::IoError> { match *v { Some(ref v) => { @@ -1232,7 +1219,7 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> { #[inline] fn serialize_seq< - T: Serializable<PrettySerializer<'a>, io::IoError>, + T: Serializable, Iter: Iterator<T> >(&mut self, mut iter: Iter) -> Result<(), io::IoError> { try!(self.wr.write_str("[")); @@ -1248,8 +1235,8 @@ impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> { #[inline] fn serialize_map< - K: Serializable<PrettySerializer<'a>, io::IoError>, - V: Serializable<PrettySerializer<'a>, io::IoError>, + K: Serializable, + V: Serializable, Iter: Iterator<(K, V)> >(&mut self, mut iter: Iter) -> Result<(), io::IoError> { try!(self.wr.write_str("{")); @@ -2200,7 +2187,6 @@ impl<A:ToJson> ToJson for Option<A> { #[cfg(test)] mod tests { - use std::io; use std::fmt::Show; use std::collections::TreeMap; @@ -2238,9 +2224,12 @@ mod tests { Frog(String, Vec<int>) } - impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Animal { + impl ser::Serializable for Animal { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { match *self { Dog => { try!(s.serialize_enum_start("Animal", "Dog", 0)); @@ -2313,9 +2302,12 @@ mod tests { c: Vec<String>, } - impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Inner { + impl ser::Serializable for Inner { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Inner", 3)); try!(s.serialize_struct_sep("a")); @@ -2407,9 +2399,12 @@ mod tests { inner: Vec<Inner>, } - impl<S: ser::Serializer<E>, E> ser::Serializable<S, E> for Outer { + impl ser::Serializable for Outer { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: ser::Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Outer", 1)); try!(s.serialize_struct_sep("inner")); @@ -2476,8 +2471,7 @@ mod tests { } fn test_encode_ok< - 'a, - T: PartialEq + Show + ToJson + ser::Serializable<Serializer<'a>, io::IoError> + T: PartialEq + Show + ToJson + ser::Serializable >(errors: &[(T, &str)]) { for &(ref value, out) in errors.iter() { let out = out.to_string(); @@ -2491,8 +2485,7 @@ mod tests { } fn test_pretty_encode_ok< - 'a, - T: PartialEq + Show + ToJson + ser::Serializable<PrettySerializer<'a>, io::IoError> + T: PartialEq + Show + ToJson + ser::Serializable >(errors: &[(T, &str)]) { for &(ref value, out) in errors.iter() { let out = out.to_string(); diff --git a/ser.rs b/ser.rs index a24f02e2..6ae9f944 100644 --- a/ser.rs +++ b/ser.rs @@ -87,35 +87,39 @@ pub trait Serializer<E> { fn serialize_enum_sep(&mut self) -> Result<(), E>; fn serialize_enum_end(&mut self) -> Result<(), E>; - fn serialize_option< - T: Serializable<Self, E> - >(&mut self, v: &Option<T>) -> Result<(), E>; + fn serialize_option<T: Serializable>(&mut self, v: &Option<T>) -> Result<(), E>; fn serialize_seq< - T: Serializable<Self, E>, + T: Serializable, Iter: Iterator<T> >(&mut self, iter: Iter) -> Result<(), E>; fn serialize_map< - K: Serializable<Self, E>, - V: Serializable<Self, E>, + K: Serializable, + V: Serializable, Iter: Iterator<(K, V)> >(&mut self, iter: Iter) -> Result<(), E>; } ////////////////////////////////////////////////////////////////////////////// -pub trait Serializable<S: Serializer<E>, E> { - fn serialize(&self, s: &mut S) -> Result<(), E>; +pub trait Serializable { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E>; } ////////////////////////////////////////////////////////////////////////////// macro_rules! impl_serializable { ($ty:ty, $method:ident, $variant:expr) => { - impl<'a, S: Serializer<E>, E> Serializable<S, E> for $ty { + impl<'a> Serializable for $ty { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.$method($variant) } } @@ -141,12 +145,13 @@ impl_serializable!(String, serialize_str, self.as_slice()) impl< 'a, - E, - S: Serializer<E>, - T: Serializable<S, E> -> Serializable<S, E> for &'a T { + T: Serializable +> Serializable for &'a T { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { (*self).serialize(s) } } @@ -154,12 +159,13 @@ impl< ////////////////////////////////////////////////////////////////////////////// impl< - E, - S: Serializer<E>, - T: Serializable<S, E> -> Serializable<S, E> for Option<T> { + T: Serializable +> Serializable for Option<T> { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_option(self) } } @@ -167,12 +173,13 @@ impl< ////////////////////////////////////////////////////////////////////////////// impl< - E, - S: Serializer<E>, - T: Serializable<S, E> -> Serializable<S, E> for Vec<T> { + T: Serializable +> Serializable for Vec<T> { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_seq(self.iter()) } } @@ -180,25 +187,27 @@ impl< ////////////////////////////////////////////////////////////////////////////// impl< - E, - S: Serializer<E>, - K: Serializable<S, E> + Eq + Hash, - V: Serializable<S, E> -> Serializable<S, E> for HashMap<K, V> { + K: Serializable + Eq + Hash, + V: Serializable +> Serializable for HashMap<K, V> { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_map(self.iter()) } } impl< - E, - S: Serializer<E>, - K: Serializable<S, E> + Ord, - V: Serializable<S, E> -> Serializable<S, E> for TreeMap<K, V> { + K: Serializable + Ord, + V: Serializable +> Serializable for TreeMap<K, V> { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_map(self.iter()) } } @@ -211,25 +220,26 @@ macro_rules! peel { macro_rules! impl_serialize_tuple { () => { - impl< - E, - S: Serializer<E> - > Serializable<S, E> for () { + impl Serializable for () { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { s.serialize_null() } } }; ( $($name:ident,)+ ) => { impl< - E, - S: Serializer<E>, - $($name:Serializable<S, E>),* - > Serializable<S, E> for ($($name,)*) { + $($name:Serializable),* + > Serializable for ($($name,)*) { #[inline] #[allow(uppercase_variables)] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { // FIXME: how can we count macro args? let mut len = 0; $({ let $name = 1; len += $name; })*; @@ -269,9 +279,12 @@ mod tests { c: HashMap<String, Option<char>>, } - impl<S: Serializer<E>, E> Serializable<S, E> for Inner { + impl Serializable for Inner { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Inner", 3)); try!(s.serialize_struct_sep("a")); @@ -294,9 +307,12 @@ mod tests { inner: Vec<Inner>, } - impl<S: Serializer<E>, E> Serializable<S, E> for Outer { + impl Serializable for Outer { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { try!(s.serialize_struct_start("Outer", 1)); try!(s.serialize_struct_sep("inner")); @@ -314,9 +330,12 @@ mod tests { Frog(String, int) } - impl<S: Serializer<E>, E> Serializable<S, E> for Animal { + impl Serializable for Animal { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { + fn serialize< + S: Serializer<E>, + E + >(&self, s: &mut S) -> Result<(), E> { match *self { Dog => { try!(s.serialize_enum_start("Animal", "Dog", 0)); @@ -508,7 +527,7 @@ mod tests { } fn serialize_option< - T: Serializable<AssertSerializer<Iter>, Error> + T: Serializable >(&mut self, v: &Option<T>) -> Result<(), Error> { match *v { Some(ref v) => { @@ -522,7 +541,7 @@ mod tests { } fn serialize_seq< - T: Serializable<AssertSerializer<Iter>, Error>, + T: Serializable, SeqIter: Iterator<T> >(&mut self, mut iter: SeqIter) -> Result<(), Error> { let (len, _) = iter.size_hint(); @@ -534,8 +553,8 @@ mod tests { } fn serialize_map< - K: Serializable<AssertSerializer<Iter>, Error>, - V: Serializable<AssertSerializer<Iter>, Error>, + K: Serializable, + V: Serializable, MapIter: Iterator<(K, V)> >(&mut self, mut iter: MapIter) -> Result<(), Error> { let (len, _) = iter.size_hint();