diff --git a/.gitignore b/.gitignore index a942eca1..e9e21997 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ /target/ /Cargo.lock -/serde2/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 22a05777..e701116d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,13 @@ [package] name = "serde" -version = "0.1.0" +version = "0.2.0" authors = ["Erick Tryzelaar "] -license = "MIT/Apache-2.0" [lib] name = "serde" -path = "src/lib.rs" [dependencies] rustc-serialize = "*" -[dependencies.serde_macros] +[dev-dependencies.serde_macros] path = "serde_macros/" diff --git a/benches/bench_enum.rs b/benches/bench_enum.rs index 7964229f..b1a97897 100644 --- a/benches/bench_enum.rs +++ b/benches/bench_enum.rs @@ -1,4 +1,4 @@ -#![feature(plugin, test)] +#![feature(custom_derive, plugin, test)] #![plugin(serde_macros)] extern crate serde; @@ -26,9 +26,16 @@ enum Animal { #[derive(Debug)] pub enum Error { - EndOfStream, + EndOfStreamError, SyntaxError, - OtherError(String), +} + +impl serde::de::Error for Error { + fn syntax_error() -> Error { Error::SyntaxError } + + fn end_of_stream_error() -> Error { Error::EndOfStreamError } + + fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError } } ////////////////////////////////////////////////////////////////////////////// @@ -38,7 +45,6 @@ mod decoder { use super::{Animal, Error}; use super::Animal::{Dog, Frog}; - use super::Error::{SyntaxError, OtherError}; use self::State::{AnimalState, IsizeState, StringState}; enum State { @@ -64,37 +70,35 @@ mod decoder { impl Decoder for AnimalDecoder { type Error = Error; - fn error(&mut self, msg: &str) -> Error { - OtherError(msg.to_string()) - } + fn error(&mut self, _: &str) -> Error { Error::SyntaxError } // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } - fn read_usize(&mut self) -> Result { Err(SyntaxError) } - fn read_u64(&mut self) -> Result { Err(SyntaxError) } - fn read_u32(&mut self) -> Result { Err(SyntaxError) } - fn read_u16(&mut self) -> Result { Err(SyntaxError) } - fn read_u8(&mut self) -> Result { Err(SyntaxError) } + fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } + fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_isize(&mut self) -> Result { match self.stack.pop() { Some(IsizeState(x)) => Ok(x), - _ => Err(SyntaxError), + _ => Err(Error::SyntaxError), } } - fn read_i64(&mut self) -> Result { Err(SyntaxError) } - fn read_i32(&mut self) -> Result { Err(SyntaxError) } - fn read_i16(&mut self) -> Result { Err(SyntaxError) } - fn read_i8(&mut self) -> Result { Err(SyntaxError) } - fn read_bool(&mut self) -> Result { Err(SyntaxError) } - fn read_f64(&mut self) -> Result { Err(SyntaxError) } - fn read_f32(&mut self) -> Result { Err(SyntaxError) } - fn read_char(&mut self) -> Result { Err(SyntaxError) } + fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(StringState(x)) => Ok(x), - _ => Err(SyntaxError), + _ => Err(Error::SyntaxError), } } @@ -109,10 +113,10 @@ mod decoder { if name == "Animal" { f(self) } else { - Err(SyntaxError) + Err(Error::SyntaxError) } } - _ => Err(SyntaxError) + _ => Err(Error::SyntaxError) } } @@ -127,12 +131,12 @@ mod decoder { self.stack.push(StringState(x0)); "Frog" } - _ => { return Err(SyntaxError); } + _ => { return Err(Error::SyntaxError); } }; let idx = match names.iter().position(|n| *n == name) { Some(idx) => idx, - None => { return Err(SyntaxError); } + None => { return Err(Error::SyntaxError); } }; f(self, idx) @@ -197,7 +201,7 @@ mod decoder { fn read_option(&mut self, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder, bool) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } #[inline] @@ -217,19 +221,19 @@ mod decoder { fn read_map(&mut self, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder, usize) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut AnimalDecoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } } } @@ -238,9 +242,6 @@ mod decoder { mod deserializer { use super::{Animal, Error}; - use super::Animal::{Dog, Frog}; - use super::Error::{EndOfStream, SyntaxError}; - use self::State::{AnimalState, IsizeState, StringState, EndState}; use serde::de; @@ -248,8 +249,7 @@ mod deserializer { AnimalState(Animal), IsizeState(isize), StringState(String), - EndState, - + UnitState, } pub struct AnimalDeserializer { @@ -260,67 +260,108 @@ mod deserializer { #[inline] pub fn new(animal: Animal) -> AnimalDeserializer { AnimalDeserializer { - stack: vec!(AnimalState(animal)), + stack: vec!(State::AnimalState(animal)), } } } - impl Iterator for AnimalDeserializer { - type Item = Result; + impl de::Deserializer for AnimalDeserializer { + type Error = Error; #[inline] - fn next(&mut self) -> Option> { + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { match self.stack.pop() { - Some(AnimalState(Dog)) => { - self.stack.push(EndState); - Some(Ok(de::Token::EnumStart("Animal", "Dog", 0))) + Some(State::AnimalState(Animal::Dog)) => { + self.stack.push(State::UnitState); + visitor.visit_enum("Animal", "Dog", DogVisitor { + de: self, + }) } - Some(AnimalState(Frog(x0, x1))) => { - self.stack.push(EndState); - self.stack.push(IsizeState(x1)); - self.stack.push(StringState(x0)); - Some(Ok(de::Token::EnumStart("Animal", "Frog", 2))) + Some(State::AnimalState(Animal::Frog(x0, x1))) => { + self.stack.push(State::IsizeState(x1)); + self.stack.push(State::StringState(x0)); + visitor.visit_enum("Animal", "Frog", FrogVisitor { + de: self, + state: 0, + }) } - Some(IsizeState(x)) => { - Some(Ok(de::Token::Isize(x))) + Some(State::IsizeState(value)) => { + visitor.visit_isize(value) } - Some(StringState(x)) => { - Some(Ok(de::Token::String(x))) + Some(State::StringState(value)) => { + visitor.visit_string(value) } - Some(EndState) => { - Some(Ok(de::Token::End)) + Some(State::UnitState) => { + visitor.visit_unit() + } + None => { + Err(Error::EndOfStreamError) } - None => None, } } } - impl de::Deserializer for AnimalDeserializer { - #[inline] - fn end_of_stream_error(&mut self) -> Error { - EndOfStream + struct DogVisitor<'a> { + de: &'a mut AnimalDeserializer, + } + + impl<'a> de::EnumVisitor for DogVisitor<'a> { + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self.de) + } + } + + struct FrogVisitor<'a> { + de: &'a mut AnimalDeserializer, + state: usize, + } + + impl<'a> de::EnumVisitor for FrogVisitor<'a> { + type Error = Error; + + fn visit_seq(&mut self, mut visitor: V) -> Result + where V: de::EnumSeqVisitor, + { + visitor.visit(self) + } + } + + impl<'a> de::SeqVisitor for FrogVisitor<'a> { + type Error = Error; + + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + match self.state { + 0 => { + self.state += 1; + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + 1 => { + self.state += 1; + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + _ => { + Ok(None) + } + } } - #[inline] - fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error { - SyntaxError + fn end(&mut self) -> Result<(), Error> { + if self.state == 2 { + Ok(()) + } else { + Err(Error::SyntaxError) + } } - #[inline] - fn unexpected_name_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn conversion_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, _field: &'static str) -> Result { - Err(SyntaxError) + fn size_hint(&self) -> (usize, Option) { + let len = 2 - self.state; + (len, Some(len)) } } } diff --git a/benches/bench_log.rs b/benches/bench_log.rs index 9e18bd26..9d39c8e2 100644 --- a/benches/bench_log.rs +++ b/benches/bench_log.rs @@ -1,4 +1,4 @@ -#![feature(collections, core, io, plugin, test)] +#![feature(custom_derive, collections, core, io, plugin, test)] #![allow(non_camel_case_types)] #![plugin(serde_macros)] @@ -10,11 +10,10 @@ use std::io::{self, ReadExt, WriteExt}; use std::num::FromPrimitive; use test::Bencher; -use serde::de; +use serde::de::{self, Deserialize, Deserializer}; use serde::json::ser::escape_str; use serde::json; -use serde::ser::Serialize; -use serde::ser; +use serde::ser::{self, Serialize, Serializer}; use rustc_serialize::Encodable; @@ -48,24 +47,28 @@ impl rustc_serialize::Encodable for HttpProtocol { impl rustc_serialize::Decodable for HttpProtocol { fn decode(d: &mut D) -> Result { - match FromPrimitive::from_uint(try!(d.read_usize())) { + match FromPrimitive::from_usize(try!(d.read_usize())) { Some(value) => Ok(value), None => Err(d.error("cannot convert from usize")), } } } -impl, E> ser::Serialize for HttpProtocol { +impl ser::Serialize for HttpProtocol { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_u8(*self as u8) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for HttpProtocol { +impl de::Deserialize for HttpProtocol { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -92,24 +95,28 @@ impl rustc_serialize::Encodable for HttpMethod { impl rustc_serialize::Decodable for HttpMethod { fn decode(d: &mut D) -> Result { - match FromPrimitive::from_uint(try!(d.read_usize())) { + match FromPrimitive::from_usize(try!(d.read_usize())) { Some(value) => Ok(value), None => Err(d.error("cannot convert from usize")), } } } -impl, E> ser::Serialize for HttpMethod { +impl ser::Serialize for HttpMethod { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_u8(*self as u8) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for HttpMethod { +impl de::Deserialize for HttpMethod { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: de::Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -136,17 +143,21 @@ impl rustc_serialize::Decodable for CacheStatus { } } -impl, E> ser::Serialize for CacheStatus { +impl ser::Serialize for CacheStatus { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_usize(*self as usize) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for CacheStatus { +impl de::Deserialize for CacheStatus { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: de::Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -182,17 +193,21 @@ impl rustc_serialize::Decodable for OriginProtocol { } } -impl, E> ser::Serialize for OriginProtocol { +impl ser::Serialize for OriginProtocol { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_u8(*self as u8) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for OriginProtocol { +impl de::Deserialize for OriginProtocol { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: de::Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -220,17 +235,21 @@ impl rustc_serialize::Decodable for ZonePlan { } } -impl, E> ser::Serialize for ZonePlan { +impl ser::Serialize for ZonePlan { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_u8(*self as u8) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for ZonePlan { +impl de::Deserialize for ZonePlan { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: de::Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -509,17 +528,21 @@ impl rustc_serialize::Decodable for Country { } } -impl, E> ser::Serialize for Country { +impl ser::Serialize for Country { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_u8(*self as u8) + fn visit< + V: ser::Visitor, + >(&self, visitor: &mut V) -> Result { + visitor.visit_u8(*self as u8) } } -impl, E> de::Deserialize for Country { +impl de::Deserialize for Country { #[inline] - fn deserialize_token(d: &mut D, token: de::Token) -> Result { - d.expect_from_primitive(token) + fn deserialize< + S: de::Deserializer, + >(state: &mut S) -> Result { + state.visit(de::PrimitiveVisitor::new()) } } @@ -652,7 +675,7 @@ fn push_all_bytes(dst: &mut Vec, src: &[u8]) { // we would have failed if `reserve` overflowed. dst.set_len(dst_len + src_len); - ::std::ptr::copy_nonoverlapping_memory( + ::std::ptr::copy_nonoverlapping( dst.as_mut_ptr().offset(dst_len as isize), src.as_ptr(), src_len); @@ -687,7 +710,7 @@ fn test_encoder() { log.encode(&mut encoder).unwrap(); } - assert_eq!(&wr[], JSON_STR); + assert_eq!(&wr, &JSON_STR); } #[bench] @@ -734,10 +757,10 @@ fn test_serializer_vec() { let log = Log::new(); let wr = Vec::with_capacity(1024); let mut serializer = json::Serializer::new(wr); - log.serialize(&mut serializer).unwrap(); + serializer.visit(&log).unwrap(); - let json = serializer.unwrap(); - assert_eq!(&json[], JSON_STR.as_bytes()); + let json = serializer.into_inner(); + assert_eq!(&json, &JSON_STR.as_bytes()); } #[bench] @@ -752,8 +775,8 @@ fn bench_serializer_vec(b: &mut Bencher) { wr.clear(); let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let _json = serializer.unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); }); } @@ -767,11 +790,11 @@ fn bench_serializer_slice(b: &mut Bencher) { b.iter(|| { for item in buf.iter_mut(){ *item = 0; } - let mut wr = &mut buf[]; + let mut wr = &mut buf[..]; let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let _json = serializer.unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); }); } @@ -783,10 +806,11 @@ fn test_serializer_my_mem_writer0() { { let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); } - assert_eq!(&wr.buf[], JSON_STR.as_bytes()); + assert_eq!(&wr.buf, &JSON_STR.as_bytes()); } #[bench] @@ -801,8 +825,8 @@ fn bench_serializer_my_mem_writer0(b: &mut Bencher) { wr.buf.clear(); let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let _json = serializer.unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); }); } @@ -814,10 +838,11 @@ fn test_serializer_my_mem_writer1() { { let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); } - assert_eq!(&wr.buf[], JSON_STR.as_bytes()); + assert_eq!(&wr.buf, &JSON_STR.as_bytes()); } #[bench] @@ -832,8 +857,8 @@ fn bench_serializer_my_mem_writer1(b: &mut Bencher) { wr.buf.clear(); let mut serializer = json::Serializer::new(wr.by_ref()); - log.serialize(&mut serializer).unwrap(); - let _json = serializer.unwrap(); + serializer.visit(&log).unwrap(); + let _json = serializer.into_inner(); }); } @@ -1017,7 +1042,7 @@ fn test_manual_serialize_vec_no_escape() { manual_serialize_no_escape(&mut wr, &log); let json = String::from_utf8(wr).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1042,7 +1067,7 @@ fn test_manual_serialize_vec_escape() { manual_serialize_escape(&mut wr, &log); let json = String::from_utf8(wr).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1068,7 +1093,7 @@ fn test_manual_serialize_my_mem_writer0_no_escape() { manual_serialize_no_escape(&mut wr, &log); let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1094,7 +1119,7 @@ fn test_manual_serialize_my_mem_writer0_escape() { manual_serialize_escape(&mut wr, &log); let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1120,7 +1145,7 @@ fn test_manual_serialize_my_mem_writer1_no_escape() { manual_serialize_no_escape(&mut wr, &log); let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1146,7 +1171,7 @@ fn test_manual_serialize_my_mem_writer1_escape() { manual_serialize_escape(&mut wr, &log); let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); + assert_eq!(&JSON_STR, &json); } #[bench] @@ -1164,116 +1189,6 @@ fn bench_manual_serialize_my_mem_writer1_escape(b: &mut Bencher) { }); } -fn direct(wr: &mut W, log: &Log) { - use serde::ser::Serializer; - - let mut serializer = json::Serializer::new(wr.by_ref()); - - serializer.serialize_struct_start("Log", 12).unwrap(); - - serializer.serialize_struct_elt("timestamp", &log.timestamp).unwrap(); - serializer.serialize_struct_elt("zone_id", &log.zone_id).unwrap(); - serializer.serialize_struct_elt("zone_plan", &(log.zone_plan as usize)).unwrap(); - serializer.serialize_struct_elt("http", &log.http).unwrap(); - serializer.serialize_struct_elt("origin", &log.origin).unwrap(); - serializer.serialize_struct_elt("country", &(log.country as usize)).unwrap(); - serializer.serialize_struct_elt("cache_status", &(log.cache_status as usize)).unwrap(); - serializer.serialize_struct_elt("server_ip", &log.server_ip).unwrap(); - serializer.serialize_struct_elt("server_name", &log.server_name).unwrap(); - serializer.serialize_struct_elt("remote_ip", &log.remote_ip).unwrap(); - serializer.serialize_struct_elt("bytes_dlv", &log.bytes_dlv).unwrap(); - serializer.serialize_struct_elt("ray_id", &log.ray_id).unwrap(); - - serializer.serialize_struct_end().unwrap(); -} - -#[test] -fn test_direct_vec() { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - direct(&mut wr, &log); - - let json = String::from_utf8(wr).unwrap(); - assert_eq!(JSON_STR, &json[]); -} - -#[bench] -fn bench_direct_vec(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - direct(&mut wr, &log); - b.bytes = wr.len() as u64; - - b.iter(|| { - let mut wr = Vec::with_capacity(1024); - direct(&mut wr, &log); - }); -} - -#[test] -fn test_direct_my_mem_writer0() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - direct(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); -} - -#[bench] -fn bench_direct_my_mem_writer0(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - direct(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - direct(&mut wr, &log); - }); -} - -#[test] -fn test_direct_my_mem_writer1() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - direct(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(JSON_STR, &json[]); -} - -#[bench] -fn bench_direct_my_mem_writer1(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - direct(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - direct(&mut wr, &log); - }); -} - -#[test] -fn test_decoder() { - use rustc_serialize::json::Json; - - let json = Json::from_str(JSON_STR).unwrap(); - let mut decoder = rustc_serialize::json::Decoder::new(json); - let log: Log = rustc_serialize::Decodable::decode(&mut decoder).unwrap(); - assert_eq!(log, Log::new()); -} - #[bench] fn bench_decoder(b: &mut Bencher) { use rustc_serialize::json::Json; @@ -1287,299 +1202,6 @@ fn bench_decoder(b: &mut Bencher) { }); } -#[test] -fn test_deserializer() { - let log: Log = json::from_str(JSON_STR).unwrap(); - assert_eq!(log, Log::new()); -} - -////////////////////////////////////////////////////////////////////////////// - -#[inline] -fn manual_reader_ignore(rdr: &mut R, buf: &mut [u8], key: &[u8]) { - let buf = &mut buf[0..key.len()]; - rdr.read(buf).unwrap(); - assert_eq!(buf, key); -} - -#[inline] -fn manual_reader_field(rdr: &mut R, buf: &mut [u8], key: &[u8]) { - let b = rdr.read_byte().unwrap(); - assert_eq!(b, b'"'); - - manual_reader_ignore(rdr, buf, key); - - let b = rdr.read_byte().unwrap(); - assert_eq!(b, b'"'); - - let b = rdr.read_byte().unwrap(); - assert_eq!(b, b':'); -} - -#[inline] -fn manual_reader_int(rdr: &mut R, buf: &mut [u8], key: &[u8]) -> i64 { - manual_reader_field(rdr, buf, key); - - let mut res = 0; - - loop { - let byte = rdr.read_byte().unwrap(); - match byte { - b'0' ... b'9' => { - res *= 10; - res += (byte as i64) - (b'0' as i64); - } - _ => { break; } - } - } - - res -} - -#[inline] -fn manual_reader_string(rdr: &mut R, buf: &mut [u8], key: &[u8]) -> String { - manual_reader_field(rdr, buf, key); - manual_reader_ignore(rdr, buf, b"\""); - - let mut idx = 0; - - loop { - let byte = rdr.read_byte().unwrap(); - match byte { - b'"' => { break; } - byte => { buf[idx] = byte; } - }; - - idx += 1; - } - - let b = rdr.read_byte().unwrap(); - assert!(b == b',' || b == b']' || b == b'}'); - - String::from_utf8(buf[..idx].to_vec()).unwrap() -} - -#[inline] -fn manual_reader_deserialize(rdr: &mut R) -> Log { - let mut buf = [0; 128]; - - manual_reader_ignore(rdr, &mut buf, b"{"); - let timestamp = manual_reader_int(rdr, &mut buf, b"timestamp"); - let zone_id = manual_reader_int(rdr, &mut buf, b"zone_id"); - let zone_plan = manual_reader_int(rdr, &mut buf, b"zone_plan"); - - manual_reader_field(rdr, &mut buf, b"http"); - manual_reader_ignore(rdr, &mut buf, b"{"); - - let protocol = manual_reader_int(rdr, &mut buf, b"protocol"); - let status = manual_reader_int(rdr, &mut buf, b"status"); - let host_status = manual_reader_int(rdr, &mut buf, b"host_status"); - let up_status = manual_reader_int(rdr, &mut buf, b"up_status"); - let method = manual_reader_int(rdr, &mut buf, b"method"); - let content_type = manual_reader_string(rdr, &mut buf, b"content_type"); - let user_agent = manual_reader_string(rdr, &mut buf, b"user_agent"); - let referer = manual_reader_string(rdr, &mut buf, b"referer"); - let request_uri = manual_reader_string(rdr, &mut buf, b"request_uri"); - - let http = Http { - protocol: FromPrimitive::from_i64(protocol).unwrap(), - status: FromPrimitive::from_i64(status).unwrap(), - host_status: FromPrimitive::from_i64(host_status).unwrap(), - up_status: FromPrimitive::from_i64(up_status).unwrap(), - method: FromPrimitive::from_i64(method).unwrap(), - content_type: content_type, - user_agent: user_agent, - referer: referer, - request_uri: request_uri, - }; - - manual_reader_ignore(rdr, &mut buf, b","); - manual_reader_field(rdr, &mut buf, b"origin"); - manual_reader_ignore(rdr, &mut buf, b"{"); - - let ip = manual_reader_string(rdr, &mut buf, b"ip"); - let port = manual_reader_int(rdr, &mut buf, b"port"); - let hostname = manual_reader_string(rdr, &mut buf, b"hostname"); - let protocol = manual_reader_int(rdr, &mut buf, b"protocol"); - - let origin = Origin { - ip: ip, - port: FromPrimitive::from_i64(port).unwrap(), - hostname: hostname, - protocol: FromPrimitive::from_i64(protocol).unwrap(), - }; - - manual_reader_ignore(rdr, &mut buf, b","); - let country = manual_reader_int(rdr, &mut buf, b"country"); - let cache_status = manual_reader_int(rdr, &mut buf, b"cache_status"); - let server_ip = manual_reader_string(rdr, &mut buf, b"server_ip"); - let server_name = manual_reader_string(rdr, &mut buf, b"server_name"); - let remote_ip = manual_reader_string(rdr, &mut buf, b"remote_ip"); - let bytes_dlv = manual_reader_int(rdr, &mut buf, b"bytes_dlv"); - let ray_id = manual_reader_string(rdr, &mut buf, b"ray_id"); - - Log { - timestamp: timestamp, - zone_id: FromPrimitive::from_i64(zone_id).unwrap(), - zone_plan: FromPrimitive::from_i64(zone_plan).unwrap(), - http: http, - origin: origin, - country: FromPrimitive::from_i64(country).unwrap(), - cache_status: FromPrimitive::from_i64(cache_status).unwrap(), - server_ip: server_ip, - server_name: server_name, - remote_ip: remote_ip, - bytes_dlv: FromPrimitive::from_i64(bytes_dlv).unwrap(), - ray_id: ray_id, - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[inline] -fn manual_iter_ignore>(mut rdr: R, buf: &mut [u8], key: &[u8]) { - let buf = &mut buf[0..key.len()]; - - for idx in range(0, key.len()) { - buf[idx] = rdr.next().unwrap(); - } - assert_eq!(buf, key); -} - -#[inline] -fn manual_iter_field>(mut rdr: R, buf: &mut [u8], key: &[u8]) { - let b = rdr.next().unwrap(); - assert_eq!(b, b'"'); - - manual_iter_ignore(rdr.by_ref(), buf, key); - - let b = rdr.next().unwrap(); - assert_eq!(b, b'"'); - - let b = rdr.next().unwrap(); - assert_eq!(b, b':'); -} - -#[inline] -fn manual_iter_int>(mut rdr: R, buf: &mut [u8], key: &[u8]) -> i64 { - manual_iter_field(rdr.by_ref(), buf, key); - - let mut res = 0; - - loop { - let byte = rdr.next().unwrap(); - match byte { - b'0' ... b'9' => { - res *= 10; - res += (byte as i64) - (b'0' as i64); - } - _ => { break; } - } - } - - res -} - -#[inline] -fn manual_iter_string>(mut rdr: R, buf: &mut [u8], key: &[u8]) -> String { - manual_iter_field(rdr.by_ref(), buf, key); - manual_iter_ignore(rdr.by_ref(), buf, b"\""); - - let mut idx = 0; - - loop { - let byte = rdr.next().unwrap(); - match byte { - b'"' => { break; } - byte => { buf[idx] = byte; } - }; - - idx += 1; - } - - let b = rdr.next().unwrap(); - assert!(b == b',' || b == b']' || b == b'}'); - - String::from_utf8(buf[..idx].to_vec()).unwrap() -} - -#[inline] -fn manual_iter_deserialize>(mut rdr: R) -> Log { - let mut buf = [0u8; 128]; - - manual_iter_ignore(rdr.by_ref(), &mut buf, b"{"); - let timestamp = manual_iter_int(rdr.by_ref(), &mut buf, b"timestamp"); - let zone_id = manual_iter_int(rdr.by_ref(), &mut buf, b"zone_id"); - let zone_plan = manual_iter_int(rdr.by_ref(), &mut buf, b"zone_plan"); - - manual_iter_field(rdr.by_ref(), &mut buf, b"http"); - manual_iter_ignore(rdr.by_ref(), &mut buf, b"{"); - - let protocol = manual_iter_int(rdr.by_ref(), &mut buf, b"protocol"); - let status = manual_iter_int(rdr.by_ref(), &mut buf, b"status"); - let host_status = manual_iter_int(rdr.by_ref(), &mut buf, b"host_status"); - let up_status = manual_iter_int(rdr.by_ref(), &mut buf, b"up_status"); - let method = manual_iter_int(rdr.by_ref(), &mut buf, b"method"); - let content_type = manual_iter_string(rdr.by_ref(), &mut buf, b"content_type"); - let user_agent = manual_iter_string(rdr.by_ref(), &mut buf, b"user_agent"); - let referer = manual_iter_string(rdr.by_ref(), &mut buf, b"referer"); - let request_uri = manual_iter_string(rdr.by_ref(), &mut buf, b"request_uri"); - - let http = Http { - protocol: FromPrimitive::from_i64(protocol).unwrap(), - status: FromPrimitive::from_i64(status).unwrap(), - host_status: FromPrimitive::from_i64(host_status).unwrap(), - up_status: FromPrimitive::from_i64(up_status).unwrap(), - method: FromPrimitive::from_i64(method).unwrap(), - content_type: content_type, - user_agent: user_agent, - referer: referer, - request_uri: request_uri, - }; - - manual_iter_ignore(rdr.by_ref(), &mut buf, b","); - manual_iter_field(rdr.by_ref(), &mut buf, b"origin"); - manual_iter_ignore(rdr.by_ref(), &mut buf, b"{"); - - let ip = manual_iter_string(rdr.by_ref(), &mut buf, b"ip"); - let port = manual_iter_int(rdr.by_ref(), &mut buf, b"port"); - let hostname = manual_iter_string(rdr.by_ref(), &mut buf, b"hostname"); - let protocol = manual_iter_int(rdr.by_ref(), &mut buf, b"protocol"); - - let origin = Origin { - ip: ip, - port: FromPrimitive::from_i64(port).unwrap(), - hostname: hostname, - protocol: FromPrimitive::from_i64(protocol).unwrap(), - }; - - manual_iter_ignore(rdr.by_ref(), &mut buf, b","); - let country = manual_iter_int(rdr.by_ref(), &mut buf, b"country"); - let cache_status = manual_iter_int(rdr.by_ref(), &mut buf, b"cache_status"); - let server_ip = manual_iter_string(rdr.by_ref(), &mut buf, b"server_ip"); - let server_name = manual_iter_string(rdr.by_ref(), &mut buf, b"server_name"); - let remote_ip = manual_iter_string(rdr.by_ref(), &mut buf, b"remote_ip"); - let bytes_dlv = manual_iter_int(rdr.by_ref(), &mut buf, b"bytes_dlv"); - let ray_id = manual_iter_string(rdr.by_ref(), &mut buf, b"ray_id"); - - Log { - timestamp: timestamp, - zone_id: FromPrimitive::from_i64(zone_id).unwrap(), - zone_plan: FromPrimitive::from_i64(zone_plan).unwrap(), - http: http, - origin: origin, - country: FromPrimitive::from_i64(country).unwrap(), - cache_status: FromPrimitive::from_i64(cache_status).unwrap(), - server_ip: server_ip, - server_name: server_name, - remote_ip: remote_ip, - bytes_dlv: FromPrimitive::from_i64(bytes_dlv).unwrap(), - ray_id: ray_id, - } -} - -////////////////////////////////////////////////////////////////////////////// - #[bench] fn bench_deserializer(b: &mut Bencher) { b.bytes = JSON_STR.len() as u64; @@ -1588,107 +1210,3 @@ fn bench_deserializer(b: &mut Bencher) { let _log: Log = json::from_str(JSON_STR).unwrap(); }); } - -#[bench] -fn bench_deserializers(b: &mut Bencher) { - let s = r#"{"timestamp":25469139677502,"zone_id":123456,"zone_plan":1,"http":{"protocol":2,"status":200,"host_status":503,"up_status":520,"method":1,"content_type":"text/html","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36","referer":"https://www.cloudflare.com/","request_uri":"/cdn-cgi/trace"},"origin":{"ip":"1.2.3.4","port":8000,"hostname":"www.example.com","protocol":2},"country":238,"cache_status":3,"server_ip":"192.168.1.1","server_name":"metal.cloudflare.com","remote_ip":"10.1.2.3","bytes_dlv":123456,"ray_id":"10c73629cce30078-LAX"}"#; - - b.bytes = s.len() as u64; - - for _ in range(0is, 10000) { - let _log: Log = json::from_str(s).unwrap(); - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[test] -fn test_reader_manual_deserializer() { - let mut rdr = JSON_STR.as_bytes(); - let log = manual_reader_deserialize(&mut rdr); - - assert_eq!(log, Log::new()); -} - -#[bench] -fn bench_reader_manual_reader_deserializer(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let mut rdr = JSON_STR.as_bytes(); - let _ = manual_reader_deserialize(&mut rdr); - }); -} - -#[bench] -fn bench_reader_manual_reader_deserializers(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - for _ in range(0is, 100000) { - let mut rdr = JSON_STR.as_bytes(); - let _ = manual_reader_deserialize(&mut rdr); - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[test] -fn test_iter_manual_iter_deserializer() { - let log = manual_iter_deserialize(JSON_STR.bytes()); - - assert_eq!(log, Log::new()); -} - -#[bench] -fn bench_iter_manual_iter_deserializer(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let _ = manual_iter_deserialize(JSON_STR.bytes()); - }); -} - -#[bench] -fn bench_iter_manual_iter_deserializers(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - for _ in range(0is, 10000) { - let _ = manual_iter_deserialize(JSON_STR.bytes()); - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[test] -fn test_iter_manual_reader_as_iter_deserializer() { - let rdr = JSON_STR.as_bytes(); - let iter = rdr.bytes().map(|x| x.unwrap()); - - let log = manual_iter_deserialize(iter); - - assert_eq!(log, Log::new()); -} - -#[bench] -fn bench_iter_manual_reader_as_iter_deserializer(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let rdr = JSON_STR.as_bytes(); - let iter = rdr.bytes().map(|x| x.unwrap()); - - let _ = manual_iter_deserialize(iter); - }); -} - -#[bench] -fn bench_iter_manual_reader_as_iter_deserializers(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - for _ in range(0is, 10000) { - let rdr = JSON_STR.as_bytes(); - let iter = rdr.bytes().map(|x| x.unwrap()); - - let _ = manual_iter_deserialize(iter); - } -} diff --git a/benches/bench_map.rs b/benches/bench_map.rs index 3017cbc3..50b243d4 100644 --- a/benches/bench_map.rs +++ b/benches/bench_map.rs @@ -1,4 +1,4 @@ -#![feature(core, plugin, test)] +#![feature(custom_derive, core, plugin, test)] #![plugin(serde_macros)] extern crate serde; @@ -19,7 +19,17 @@ use serde::de::{Deserializer, Deserialize}; pub enum Error { EndOfStream, SyntaxError, - OtherError(String), + MissingField, +} + +impl serde::de::Error for Error { + fn syntax_error() -> Error { Error::SyntaxError } + + fn end_of_stream_error() -> Error { Error::EndOfStream } + + fn missing_field_error(_: &'static str) -> Error { + Error::MissingField + } } ////////////////////////////////////////////////////////////////////////////// @@ -30,7 +40,6 @@ mod decoder { use rustc_serialize; use super::Error; - use super::Error::{EndOfStream, SyntaxError, OtherError}; use self::Value::{StringValue, IsizeValue}; enum Value { @@ -58,39 +67,39 @@ mod decoder { impl rustc_serialize::Decoder for IsizeDecoder { type Error = Error; - fn error(&mut self, msg: &str) -> Error { - OtherError(msg.to_string()) + fn error(&mut self, _msg: &str) -> Error { + Error::SyntaxError } // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } - fn read_usize(&mut self) -> Result { Err(SyntaxError) } - fn read_u64(&mut self) -> Result { Err(SyntaxError) } - fn read_u32(&mut self) -> Result { Err(SyntaxError) } - fn read_u16(&mut self) -> Result { Err(SyntaxError) } - fn read_u8(&mut self) -> Result { Err(SyntaxError) } + fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } + fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_isize(&mut self) -> Result { match self.stack.pop() { Some(IsizeValue(x)) => Ok(x), - Some(_) => Err(SyntaxError), - None => Err(EndOfStream), + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStream), } } - fn read_i64(&mut self) -> Result { Err(SyntaxError) } - fn read_i32(&mut self) -> Result { Err(SyntaxError) } - fn read_i16(&mut self) -> Result { Err(SyntaxError) } - fn read_i8(&mut self) -> Result { Err(SyntaxError) } - fn read_bool(&mut self) -> Result { Err(SyntaxError) } - fn read_f64(&mut self) -> Result { Err(SyntaxError) } - fn read_f32(&mut self) -> Result { Err(SyntaxError) } - fn read_char(&mut self) -> Result { Err(SyntaxError) } + fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(StringValue(x)) => Ok(x), - Some(_) => Err(SyntaxError), - None => Err(EndOfStream), + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStream), } } @@ -165,19 +174,19 @@ mod decoder { fn read_option(&mut self, _f: F) -> Result where F: FnOnce(&mut IsizeDecoder, bool) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_seq(&mut self, _f: F) -> Result where F: FnOnce(&mut IsizeDecoder, usize) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_seq_elt(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut IsizeDecoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } #[inline] @@ -198,7 +207,7 @@ mod decoder { f(self) } None => { - Err(SyntaxError) + Err(Error::SyntaxError) } } } @@ -216,39 +225,94 @@ mod decoder { mod deserializer { use std::collections::HashMap; - use std::collections::hash_map::IntoIter; + use std::collections::hash_map; use super::Error; - use super::Error::{EndOfStream, SyntaxError}; - use self::State::{StartState, KeyOrEndState, ValueState, EndState}; use serde::de; #[derive(PartialEq, Debug)] enum State { StartState, - KeyOrEndState, + KeyState(String), ValueState(isize), - EndState, } pub struct IsizeDeserializer { stack: Vec, - len: usize, - iter: IntoIter, + iter: hash_map::IntoIter, } impl IsizeDeserializer { #[inline] pub fn new(values: HashMap) -> IsizeDeserializer { IsizeDeserializer { - stack: vec!(StartState), - len: values.len(), + stack: vec!(State::StartState), iter: values.into_iter(), } } } + impl de::Deserializer for IsizeDeserializer { + type Error = Error; + + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + match self.stack.pop() { + Some(State::StartState) => { + visitor.visit_map(self) + } + Some(State::KeyState(key)) => { + visitor.visit_string(key) + } + Some(State::ValueState(value)) => { + visitor.visit_isize(value) + } + None => { + Err(Error::EndOfStream) + } + } + } + } + + impl de::MapVisitor for IsizeDeserializer { + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + match self.iter.next() { + Some((key, value)) => { + self.stack.push(State::ValueState(value)); + self.stack.push(State::KeyState(key)); + Ok(Some(try!(de::Deserialize::deserialize(self)))) + } + None => { + Ok(None) + } + } + } + + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + de::Deserialize::deserialize(self) + } + + fn end(&mut self) -> Result<(), Error> { + match self.iter.next() { + Some(_) => Err(Error::SyntaxError), + None => Ok(()), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + +/* impl Iterator for IsizeDeserializer { type Item = Result; @@ -310,9 +374,10 @@ mod deserializer { fn missing_field< T: de::Deserialize >(&mut self, _field: &'static str) -> Result { - Err(SyntaxError) + Err(Error::SyntaxError) } } +*/ } ////////////////////////////////////////////////////////////////////////////// @@ -338,7 +403,7 @@ fn bench_decoder_000(b: &mut Bencher) { fn bench_decoder_003(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); - for i in range(0is, 3) { + for i in range(0, 3) { m.insert(i.to_string(), i); } run_decoder(decoder::IsizeDecoder::new(m.clone()), m) @@ -349,7 +414,7 @@ fn bench_decoder_003(b: &mut Bencher) { fn bench_decoder_100(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); - for i in range(0is, 100) { + for i in range(0, 100) { m.insert(i.to_string(), i); } run_decoder(decoder::IsizeDecoder::new(m.clone()), m) @@ -357,9 +422,9 @@ fn bench_decoder_100(b: &mut Bencher) { } fn run_deserializer< - D: Deserializer, + D: Deserializer, E: Debug, - T: Clone + PartialEq + Debug + Deserialize + T: Clone + PartialEq + Debug + Deserialize >(mut d: D, value: T) { let v: T = Deserialize::deserialize(&mut d).unwrap(); @@ -378,7 +443,7 @@ fn bench_deserializer_000(b: &mut Bencher) { fn bench_deserializer_003(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); - for i in range(0is, 3) { + for i in range(0, 3) { m.insert(i.to_string(), i); } run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) @@ -389,7 +454,7 @@ fn bench_deserializer_003(b: &mut Bencher) { fn bench_deserializer_100(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); - for i in range(0is, 100) { + for i in range(0, 100) { m.insert(i.to_string(), i); } run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) diff --git a/benches/bench_struct.rs b/benches/bench_struct.rs index 1803de44..0e58ed41 100644 --- a/benches/bench_struct.rs +++ b/benches/bench_struct.rs @@ -1,4 +1,4 @@ -#![feature(plugin, test)] +#![feature(custom_derive, plugin, test)] #![plugin(serde_macros)] extern crate serde; @@ -35,11 +35,21 @@ struct Outer { #[derive(Debug)] pub enum Error { EndOfStream, - SyntaxError(String), - UnexpectedName(String), - ConversionError(String), - MissingField(&'static str), - OtherError(String), + SyntaxError, + UnexpectedName, + ConversionError, + MissingField, + OtherError, +} + +impl serde::de::Error for Error { + fn syntax_error() -> Error { Error::SyntaxError } + + fn end_of_stream_error() -> Error { Error::EndOfStream } + + fn missing_field_error(_: &'static str) -> Error { + Error::MissingField + } } mod decoder { @@ -92,8 +102,8 @@ mod decoder { impl Decoder for OuterDecoder { type Error = Error; - fn error(&mut self, msg: &str) -> Error { - Error::OtherError(msg.to_string()) + fn error(&mut self, _msg: &str) -> Error { + Error::OtherError } // Primitive types: @@ -101,40 +111,40 @@ mod decoder { fn read_nil(&mut self) -> Result<(), Error> { match self.stack.pop() { Some(NullState) => Ok(()), - _ => Err(Error::SyntaxError("NullState".to_string())), + _ => Err(Error::SyntaxError), } } #[inline] fn read_usize(&mut self) -> Result { match self.stack.pop() { Some(UsizeState(value)) => Ok(value), - _ => Err(Error::SyntaxError("UintState".to_string())), + _ => Err(Error::SyntaxError), } } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_u8(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_isize(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError("".to_string())) } + fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_char(&mut self) -> Result { match self.stack.pop() { Some(CharState(c)) => Ok(c), - _ => Err(Error::SyntaxError("".to_string())), + _ => Err(Error::SyntaxError), } } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(StringState(value)) => Ok(value), - _ => Err(Error::SyntaxError("".to_string())), + _ => Err(Error::SyntaxError), } } @@ -142,31 +152,31 @@ mod decoder { fn read_enum(&mut self, _name: &str, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where F: FnOnce(&mut OuterDecoder, usize) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where F: FnOnce(&mut OuterDecoder, usize) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } #[inline] @@ -180,7 +190,7 @@ mod decoder { self.stack.push(FieldState("inner")); f(self) } else { - Err(Error::SyntaxError("expected Outer".to_string())) + Err(Error::SyntaxError) } } Some(InnerState(Inner { a: (), b, c })) => { @@ -195,10 +205,10 @@ mod decoder { self.stack.push(FieldState("a")); f(self) } else { - Err(Error::SyntaxError("expected Inner".to_string())) + Err(Error::SyntaxError) } } - _ => Err(Error::SyntaxError("expected InnerState or OuterState".to_string())), + _ => Err(Error::SyntaxError), } } #[inline] @@ -210,35 +220,35 @@ mod decoder { if f_name == name { f(self) } else { - Err(Error::SyntaxError("expected FieldState".to_string())) + Err(Error::SyntaxError) } } - _ => Err(Error::SyntaxError("expected FieldState".to_string())) + _ => Err(Error::SyntaxError) } } fn read_tuple(&mut self, _len: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where F: FnOnce(&mut OuterDecoder) -> Result, { - Err(Error::SyntaxError("".to_string())) + Err(Error::SyntaxError) } // Specialized types: @@ -248,7 +258,7 @@ mod decoder { { match self.stack.pop() { Some(OptionState(b)) => f(self, b), - _ => Err(Error::SyntaxError("expected OptionState".to_string())), + _ => Err(Error::SyntaxError), } } @@ -264,7 +274,7 @@ mod decoder { } f(self, len) } - _ => Err(Error::SyntaxError("expected VecState".to_string())) + _ => Err(Error::SyntaxError) } } #[inline] @@ -295,7 +305,7 @@ mod decoder { } f(self, len) } - _ => Err(Error::SyntaxError("expected MapState".to_string())), + _ => Err(Error::SyntaxError), } } #[inline] @@ -318,39 +328,24 @@ mod decoder { mod deserializer { use std::collections::HashMap; + use std::collections::hash_map; + use std::vec; use super::{Outer, Inner}; use super::Error; use serde::de; - use self::State::{ - OuterState, - InnerState, - FieldState, - NullState, - UsizeState, - CharState, - StringState, - OptionState, - //TupleState(usize), - VecState, - MapState, - EndState, - }; - #[derive(Debug)] enum State { OuterState(Outer), InnerState(Inner), - FieldState(&'static str), + StrState(&'static str), NullState, UsizeState(usize), CharState(char), StringState(String), OptionState(bool), - //TupleState(uint), VecState(Vec), MapState(HashMap>), - EndState, } pub struct OuterDeserializer { @@ -361,101 +356,242 @@ mod deserializer { #[inline] pub fn new(outer: Outer) -> OuterDeserializer { OuterDeserializer { - stack: vec!(OuterState(outer)), + stack: vec!(State::OuterState(outer)), } } } - impl Iterator for OuterDeserializer { - type Item = Result; + impl de::Deserializer for OuterDeserializer { + type Error = Error; - #[inline] - fn next(&mut self) -> Option> { + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { match self.stack.pop() { - Some(OuterState(Outer { inner })) => { - self.stack.push(EndState); - self.stack.push(VecState(inner)); - self.stack.push(FieldState("inner")); - Some(Ok(de::Token::StructStart("Outer", 1))) - } - Some(InnerState(Inner { a: (), b, c })) => { - self.stack.push(EndState); - self.stack.push(MapState(c)); - self.stack.push(FieldState("c")); + Some(State::OuterState(Outer { inner })) => { + self.stack.push(State::VecState(inner)); + self.stack.push(State::StrState("inner")); - self.stack.push(UsizeState(b)); - self.stack.push(FieldState("b")); + visitor.visit_named_map("Outer", OuterMapVisitor { + de: self, + state: 0, + }) + } + Some(State::InnerState(Inner { a: (), b, c })) => { + self.stack.push(State::MapState(c)); + self.stack.push(State::StrState("c")); - self.stack.push(NullState); - self.stack.push(FieldState("a")); - Some(Ok(de::Token::StructStart("Inner", 3))) + self.stack.push(State::UsizeState(b)); + self.stack.push(State::StrState("b")); + + self.stack.push(State::NullState); + self.stack.push(State::StrState("a")); + + visitor.visit_named_map("Inner", InnerMapVisitor { + de: self, + state: 0, + }) } - Some(FieldState(name)) => Some(Ok(de::Token::Str(name))), - Some(VecState(value)) => { - self.stack.push(EndState); - let len = value.len(); - for inner in value.into_iter().rev() { - self.stack.push(InnerState(inner)); - } - Some(Ok(de::Token::SeqStart(len))) + Some(State::VecState(value)) => { + visitor.visit_seq(OuterSeqVisitor { + de: self, + iter: value.into_iter(), + }) } - Some(MapState(value)) => { - self.stack.push(EndState); - let len = value.len(); - for (key, value) in value { - match value { - Some(c) => { - self.stack.push(CharState(c)); - self.stack.push(OptionState(true)); - } - None => { - self.stack.push(OptionState(false)); - } - } - self.stack.push(StringState(key)); - } - Some(Ok(de::Token::MapStart(len))) + Some(State::MapState(value)) => { + visitor.visit_map(MapVisitor { + de: self, + iter: value.into_iter(), + }) } - //Some(TupleState(len)) => Some(Ok(de::Token::TupleStart(len))), - Some(NullState) => Some(Ok(de::Token::Null)), - Some(UsizeState(x)) => Some(Ok(de::Token::Usize(x))), - Some(CharState(x)) => Some(Ok(de::Token::Char(x))), - Some(StringState(x)) => Some(Ok(de::Token::String(x))), - Some(OptionState(x)) => Some(Ok(de::Token::Option(x))), - Some(EndState) => { - Some(Ok(de::Token::End)) + Some(State::NullState) => { + visitor.visit_unit() } - None => None, + Some(State::UsizeState(x)) => { + visitor.visit_usize(x) + } + Some(State::CharState(x)) => { + visitor.visit_char(x) + } + Some(State::StrState(x)) => { + visitor.visit_str(x) + } + Some(State::StringState(x)) => { + visitor.visit_string(x) + } + Some(State::OptionState(false)) => { + visitor.visit_none() + } + Some(State::OptionState(true)) => { + visitor.visit_some(self) + } + None => Err(Error::EndOfStream), } } } - impl de::Deserializer for OuterDeserializer { - #[inline] - fn end_of_stream_error(&mut self) -> Error { - Error::EndOfStream + struct OuterMapVisitor<'a> { + de: &'a mut OuterDeserializer, + state: usize, + } + + impl<'a> de::MapVisitor for OuterMapVisitor<'a> { + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + match self.state { + 0 => { + self.state += 1; + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + _ => { + Ok(None) + } + } } - #[inline] - fn syntax_error(&mut self, token: de::Token, expected: &[de::TokenKind]) -> Error { - Error::SyntaxError(format!("expected {:?}, found {:?}", expected, token)) + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + de::Deserialize::deserialize(self.de) } - #[inline] - fn unexpected_name_error(&mut self, token: de::Token) -> Error { - Error::UnexpectedName(format!("found {:?}", token)) + fn end(&mut self) -> Result<(), Error> { + if self.state == 1 { + Ok(()) + } else { + Err(Error::SyntaxError) + } } - #[inline] - fn conversion_error(&mut self, token: de::Token) -> Error { - Error::UnexpectedName(format!("found {:?}", token)) + fn size_hint(&self) -> (usize, Option) { + let len = 1 - self.state; + (len, Some(len)) + } + } + + struct OuterSeqVisitor<'a> { + de: &'a mut OuterDeserializer, + iter: vec::IntoIter, + } + + impl<'a> de::SeqVisitor for OuterSeqVisitor<'a> { + type Error = Error; + + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + match self.iter.next() { + Some(value) => { + self.de.stack.push(State::InnerState(value)); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + None => { + Ok(None) + } + } } - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, field: &'static str) -> Result { - Err(Error::MissingField(field)) + fn end(&mut self) -> Result<(), Error> { + match self.iter.next() { + Some(_) => Err(Error::SyntaxError), + None => Ok(()), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + struct InnerMapVisitor<'a> { + de: &'a mut OuterDeserializer, + state: usize, + } + + impl<'a> de::MapVisitor for InnerMapVisitor<'a> { + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + match self.state { + 0 ... 2 => { + self.state += 1; + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + _ => { + Ok(None) + } + } + } + + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + de::Deserialize::deserialize(self.de) + } + + fn end(&mut self) -> Result<(), Error> { + if self.state == 1 { + Ok(()) + } else { + Err(Error::SyntaxError) + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = 1 - self.state; + (len, Some(len)) + } + } + + struct MapVisitor<'a> { + de: &'a mut OuterDeserializer, + iter: hash_map::IntoIter>, + } + + impl<'a> de::MapVisitor for MapVisitor<'a> { + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + match self.iter.next() { + Some((key, Some(value))) => { + self.de.stack.push(State::CharState(value)); + self.de.stack.push(State::OptionState(true)); + self.de.stack.push(State::StringState(key)); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + Some((key, None)) => { + self.de.stack.push(State::OptionState(false)); + self.de.stack.push(State::StringState(key)); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + None => { + Ok(None) + } + } + } + + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + de::Deserialize::deserialize(self.de) + } + + fn end(&mut self) -> Result<(), Error> { + match self.iter.next() { + Some(_) => Err(Error::SyntaxError), + None => Ok(()), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() } } } diff --git a/benches/bench_vec.rs b/benches/bench_vec.rs index 1b24f194..90706963 100644 --- a/benches/bench_vec.rs +++ b/benches/bench_vec.rs @@ -16,9 +16,16 @@ use serde::de::{Deserializer, Deserialize}; #[derive(PartialEq, Debug)] pub enum Error { - EndOfStream, + EndOfStreamError, SyntaxError, - OtherError(String), +} + +impl serde::de::Error for Error { + fn syntax_error() -> Error { Error::SyntaxError } + + fn end_of_stream_error() -> Error { Error::EndOfStreamError } + + fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError } } ////////////////////////////////////////////////////////////////////////////// @@ -28,158 +35,155 @@ mod decoder { use rustc_serialize; use super::Error; - use super::Error::{EndOfStream, SyntaxError, OtherError}; - pub struct IsizeDecoder { + pub struct UsizeDecoder { len: usize, - iter: vec::IntoIter, + iter: vec::IntoIter, } - impl IsizeDecoder { + impl UsizeDecoder { #[inline] - pub fn new(values: Vec) -> IsizeDecoder { - IsizeDecoder { + pub fn new(values: Vec) -> UsizeDecoder { + UsizeDecoder { len: values.len(), iter: values.into_iter(), } } } - impl rustc_serialize::Decoder for IsizeDecoder { + impl rustc_serialize::Decoder for UsizeDecoder { type Error = Error; - fn error(&mut self, msg: &str) -> Error { - OtherError(msg.to_string()) - } + fn error(&mut self, _: &str) -> Error { Error::SyntaxError } // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } - fn read_usize(&mut self) -> Result { Err(SyntaxError) } - fn read_u64(&mut self) -> Result { Err(SyntaxError) } - fn read_u32(&mut self) -> Result { Err(SyntaxError) } - fn read_u16(&mut self) -> Result { Err(SyntaxError) } - fn read_u8(&mut self) -> Result { Err(SyntaxError) } + fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } #[inline] - fn read_isize(&mut self) -> Result { + fn read_usize(&mut self) -> Result { match self.iter.next() { Some(value) => Ok(value), - None => Err(EndOfStream), + None => Err(Error::EndOfStreamError), } } - fn read_i64(&mut self) -> Result { Err(SyntaxError) } - fn read_i32(&mut self) -> Result { Err(SyntaxError) } - fn read_i16(&mut self) -> Result { Err(SyntaxError) } - fn read_i8(&mut self) -> Result { Err(SyntaxError) } - fn read_bool(&mut self) -> Result { Err(SyntaxError) } - fn read_f64(&mut self) -> Result { Err(SyntaxError) } - fn read_f32(&mut self) -> Result { Err(SyntaxError) } - fn read_char(&mut self) -> Result { Err(SyntaxError) } - fn read_str(&mut self) -> Result { Err(SyntaxError) } + fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_str(&mut self) -> Result { Err(Error::SyntaxError) } // Compound types: fn read_enum(&mut self, _name: &str, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, + F: FnOnce(&mut UsizeDecoder, usize) -> Result, { Err(Error::SyntaxError) } fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, + F: FnOnce(&mut UsizeDecoder, usize) -> Result, { Err(Error::SyntaxError) } fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { Err(Error::SyntaxError) } // Specialized types: fn read_option(&mut self, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, bool) -> Result, + F: FnOnce(&mut UsizeDecoder, bool) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } #[inline] fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, + F: FnOnce(&mut UsizeDecoder, usize) -> Result, { let len = self.len; f(self, len) } #[inline] fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { f(self) } fn read_map(&mut self, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, + F: FnOnce(&mut UsizeDecoder, usize) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, + F: FnOnce(&mut UsizeDecoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } } @@ -202,34 +206,32 @@ mod decoder { impl rustc_serialize::Decoder for U8Decoder { type Error = Error; - fn error(&mut self, msg: &str) -> Error { - OtherError(msg.to_string()) - } + fn error(&mut self, _: &str) -> Error { Error::SyntaxError } // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } - fn read_usize(&mut self) -> Result { Err(SyntaxError) } - fn read_u64(&mut self) -> Result { Err(SyntaxError) } - fn read_u32(&mut self) -> Result { Err(SyntaxError) } - fn read_u16(&mut self) -> Result { Err(SyntaxError) } + fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } + fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } #[inline] fn read_u8(&mut self) -> Result { match self.iter.next() { Some(value) => Ok(value), - None => Err(EndOfStream), + None => Err(Error::EndOfStreamError), } } #[inline] - fn read_isize(&mut self) -> Result { Err(SyntaxError) } - fn read_i64(&mut self) -> Result { Err(SyntaxError) } - fn read_i32(&mut self) -> Result { Err(SyntaxError) } - fn read_i16(&mut self) -> Result { Err(SyntaxError) } - fn read_i8(&mut self) -> Result { Err(SyntaxError) } - fn read_bool(&mut self) -> Result { Err(SyntaxError) } - fn read_f64(&mut self) -> Result { Err(SyntaxError) } - fn read_f32(&mut self) -> Result { Err(SyntaxError) } - fn read_char(&mut self) -> Result { Err(SyntaxError) } - fn read_str(&mut self) -> Result { Err(SyntaxError) } + fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } + fn read_str(&mut self) -> Result { Err(Error::SyntaxError) } // Compound types: fn read_enum(&mut self, _name: &str, _f: F) -> Result where @@ -302,7 +304,7 @@ mod decoder { fn read_option(&mut self, _f: F) -> Result where F: FnOnce(&mut U8Decoder, bool) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } #[inline] @@ -322,19 +324,19 @@ mod decoder { fn read_map(&mut self, _f: F) -> Result where F: FnOnce(&mut U8Decoder, usize) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut U8Decoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where F: FnOnce(&mut U8Decoder) -> Result, { - Err(SyntaxError) + Err(Error::SyntaxError) } } } @@ -346,8 +348,6 @@ mod deserializer { use std::vec; use super::Error; - use super::Error::{EndOfStream, SyntaxError}; - use self::State::{StartState, SepOrEndState, EndState}; use serde::de; @@ -358,151 +358,141 @@ mod deserializer { EndState, } - pub struct IsizeDeserializer { + pub struct Deserializer { state: State, + iter: vec::IntoIter, len: usize, - iter: vec::IntoIter, + value: Option, } - impl IsizeDeserializer { + impl Deserializer { #[inline] - pub fn new(values: Vec) -> IsizeDeserializer { - IsizeDeserializer { - state: StartState, - len: values.len(), + pub fn new(values: Vec) -> Deserializer { + let len = values.len(); + Deserializer { + state: State::StartState, iter: values.into_iter(), + len: len, + value: None, } } } - impl Iterator for IsizeDeserializer { - type Item = Result; + impl de::Deserializer for Deserializer { + type Error = Error; #[inline] - fn next(&mut self) -> Option> { + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { match self.state { - StartState => { - self.state = SepOrEndState; - Some(Ok(de::Token::SeqStart(self.len))) + State::StartState => { + self.state = State::SepOrEndState; + visitor.visit_seq(self) } - SepOrEndState => { - match self.iter.next() { - Some(value) => { - Some(Ok(de::Token::Isize(value))) - } - None => { - self.state = EndState; - Some(Ok(de::Token::End)) - } - } + State::SepOrEndState => { + visitor.visit_usize(self.value.take().unwrap()) } - EndState => { - None + State::EndState => { + Err(Error::EndOfStreamError) } } } } - impl de::Deserializer for IsizeDeserializer { - #[inline] - fn end_of_stream_error(&mut self) -> Error { - EndOfStream - } + impl de::SeqVisitor for Deserializer { + type Error = Error; #[inline] - fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error { - SyntaxError - } - - #[inline] - fn unexpected_name_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn conversion_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, _field: &'static str) -> Result { - Err(SyntaxError) - } - } - - pub struct U8Deserializer { - state: State, - len: usize, - iter: vec::IntoIter, - } - - impl U8Deserializer { - #[inline] - pub fn new(values: Vec) -> U8Deserializer { - U8Deserializer { - state: StartState, - len: values.len(), - iter: values.into_iter(), + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + match self.iter.next() { + Some(value) => { + self.len -= 1; + self.value = Some(value); + Ok(Some(try!(de::Deserialize::deserialize(self)))) + } + None => { + self.state = State::EndState; + Ok(None) + } } } - } - - impl Iterator for U8Deserializer { - type Item = Result; #[inline] - fn next(&mut self) -> Option> { + fn end(&mut self) -> Result<(), Error> { + match self.iter.next() { + Some(_) => Err(Error::SyntaxError), + None => { + self.state = State::EndState; + Ok(()) + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } + } + + impl de::Deserializer for Deserializer { + type Error = Error; + + #[inline] + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { match self.state { - StartState => { - self.state = SepOrEndState; - Some(Ok(de::Token::SeqStart(self.len))) + State::StartState => { + self.state = State::SepOrEndState; + visitor.visit_seq(self) } - SepOrEndState => { - match self.iter.next() { - Some(value) => { - Some(Ok(de::Token::U8(value))) - } - None => { - self.state = EndState; - Some(Ok(de::Token::End)) - } - } + State::SepOrEndState => { + visitor.visit_u8(self.value.take().unwrap()) } - EndState => { - None + State::EndState => { + Err(Error::EndOfStreamError) } } } } - impl de::Deserializer for U8Deserializer { + impl de::SeqVisitor for Deserializer { + type Error = Error; + #[inline] - fn end_of_stream_error(&mut self) -> Error { - EndOfStream + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + match self.iter.next() { + Some(value) => { + self.len -= 1; + self.value = Some(value); + Ok(Some(try!(de::Deserialize::deserialize(self)))) + } + None => { + self.state = State::EndState; + Ok(None) + } + } } #[inline] - fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error { - SyntaxError + fn end(&mut self) -> Result<(), Error> { + match self.iter.next() { + Some(_) => Err(Error::SyntaxError), + None => { + self.state = State::EndState; + Ok(()) + } + } } #[inline] - fn unexpected_name_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn conversion_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, _field: &'static str) -> Result { - Err(SyntaxError) + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) } } } @@ -519,9 +509,9 @@ fn run_decoder< } fn run_deserializer< - D: Deserializer, + D: Deserializer, E: Debug, - T: Clone + PartialEq + Debug + Deserialize + T: Clone + PartialEq + Debug + Deserialize >(mut d: D, value: T) { let v: T = Deserialize::deserialize(&mut d).unwrap(); @@ -529,26 +519,26 @@ fn run_deserializer< } #[bench] -fn bench_decoder_int_000(b: &mut Bencher) { +fn bench_decoder_usize_000(b: &mut Bencher) { b.iter(|| { - let v: Vec = vec!(); - run_decoder(decoder::IsizeDecoder::new(v.clone()), v) + let v: Vec = vec!(); + run_decoder(decoder::UsizeDecoder::new(v.clone()), v) }) } #[bench] -fn bench_decoder_int_003(b: &mut Bencher) { +fn bench_decoder_usize_003(b: &mut Bencher) { b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_decoder(decoder::IsizeDecoder::new(v.clone()), v) + let v: Vec = vec!(1, 2, 3); + run_decoder(decoder::UsizeDecoder::new(v.clone()), v) }) } #[bench] -fn bench_decoder_int_100(b: &mut Bencher) { +fn bench_decoder_usize_100(b: &mut Bencher) { b.iter(|| { - let v: Vec = range(0is, 100).collect(); - run_decoder(decoder::IsizeDecoder::new(v.clone()), v) + let v: Vec = range(0, 100).collect(); + run_decoder(decoder::UsizeDecoder::new(v.clone()), v) }) } @@ -577,26 +567,26 @@ fn bench_decoder_u8_100(b: &mut Bencher) { } #[bench] -fn bench_deserializer_int_000(b: &mut Bencher) { +fn bench_deserializer_usize_000(b: &mut Bencher) { b.iter(|| { - let v: Vec = vec!(); - run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v) + let v: Vec = vec!(); + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } #[bench] -fn bench_deserializer_int_003(b: &mut Bencher) { +fn bench_deserializer_usize_003(b: &mut Bencher) { b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v) + let v: Vec = vec!(1, 2, 3); + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } #[bench] -fn bench_deserializer_int_100(b: &mut Bencher) { +fn bench_deserializer_usize_100(b: &mut Bencher) { b.iter(|| { - let v: Vec = range(0is, 100).collect(); - run_deserializer(deserializer::IsizeDeserializer::new(v.clone()), v) + let v: Vec = range(0, 100).collect(); + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } @@ -604,7 +594,7 @@ fn bench_deserializer_int_100(b: &mut Bencher) { fn bench_deserializer_u8_000(b: &mut Bencher) { b.iter(|| { let v: Vec = vec!(); - run_deserializer(deserializer::U8Deserializer::new(v.clone()), v) + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } @@ -612,7 +602,7 @@ fn bench_deserializer_u8_000(b: &mut Bencher) { fn bench_deserializer_u8_003(b: &mut Bencher) { b.iter(|| { let v: Vec = vec!(1, 2, 3); - run_deserializer(deserializer::U8Deserializer::new(v.clone()), v) + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } @@ -620,6 +610,6 @@ fn bench_deserializer_u8_003(b: &mut Bencher) { fn bench_deserializer_u8_100(b: &mut Bencher) { b.iter(|| { let v: Vec = range(0u8, 100).collect(); - run_deserializer(deserializer::U8Deserializer::new(v.clone()), v) + run_deserializer(deserializer::Deserializer::new(v.clone()), v) }) } diff --git a/benches/json.rs b/benches/json.rs deleted file mode 100644 index ab819d5b..00000000 --- a/benches/json.rs +++ /dev/null @@ -1,311 +0,0 @@ -#![feature(core, plugin, test)] -#![plugin(serde_macros)] - -extern crate serde; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use std::collections::BTreeMap; -use std::string; -use rustc_serialize as serialize; -use test::Bencher; - -use serde::de::Token; - -use serde::json::{Parser, Value, from_str}; - -macro_rules! treemap { - ($($k:expr => $v:expr),*) => ({ - let mut _m = ::std::collections::BTreeMap::new(); - $(_m.insert($k, $v);)* - _m - }) -} - -fn json_str(count: usize) -> string::String { - let mut src = "[".to_string(); - for _ in range(0, count) { - src.push_str(r#"{"a":true,"b":null,"c":3.1415,"d":"Hello world","e":[1,2,3]},"#); - } - src.push_str("{}]"); - src -} - -fn pretty_json_str(count: usize) -> string::String { - let mut src = "[\n".to_string(); - for _ in range(0, count) { - src.push_str( - concat!( - " {\n", - " \"a\": true,\n", - " \"b\": null,\n", - " \"c\": 3.1415,\n", - " \"d\": \"Hello world\",\n", - " \"e\": [\n", - " 1,\n", - " 2,\n", - " 3\n", - " ]\n", - " },\n" - ) - ); - } - src.push_str(" {}\n]"); - src -} - -fn encoder_json(count: usize) -> serialize::json::Json { - use rustc_serialize::json::Json; - - let mut list = vec!(); - for _ in range(0, count) { - list.push(Json::Object(treemap!( - "a".to_string() => Json::Boolean(true), - "b".to_string() => Json::Null, - "c".to_string() => Json::F64(3.1415), - "d".to_string() => Json::String("Hello world".to_string()), - "e".to_string() => Json::Array(vec!( - Json::U64(1), - Json::U64(2), - Json::U64(3) - )) - ))); - } - list.push(Json::Object(BTreeMap::new())); - Json::Array(list) -} - -fn serializer_json(count: usize) -> Value { - let mut list = vec!(); - for _ in range(0, count) { - list.push(Value::Object(treemap!( - "a".to_string() => Value::Boolean(true), - "b".to_string() => Value::Null, - "c".to_string() => Value::Floating(3.1415), - "d".to_string() => Value::String("Hello world".to_string()), - "e".to_string() => Value::Array(vec!( - Value::Integer(1), - Value::Integer(2), - Value::Integer(3) - )) - ))); - } - list.push(Value::Object(BTreeMap::new())); - Value::Array(list) -} - -fn bench_encoder(b: &mut Bencher, count: usize) { - let src = json_str(count); - let json = encoder_json(count); - - b.iter(|| { - assert_eq!(json.to_string(), src); - }); -} - -fn bench_encoder_pretty(b: &mut Bencher, count: usize) { - let src = pretty_json_str(count); - let json = encoder_json(count); - - b.iter(|| { - assert_eq!(json.pretty().to_string(), src); - }); -} - -fn bench_serializer(b: &mut Bencher, count: usize) { - let src = json_str(count); - let json = serializer_json(count); - - b.iter(|| { - assert_eq!(json.to_string(), src); - }); -} - -fn bench_serializer_pretty(b: &mut Bencher, count: usize) { - let src = pretty_json_str(count); - let json = serializer_json(count); - - b.iter(|| { - assert_eq!(json.to_pretty_string(), src); - }); -} - -fn bench_decoder(b: &mut Bencher, count: usize) { - let src = json_str(count); - let json = encoder_json(count); - b.iter(|| { - assert_eq!(json, serialize::json::Json::from_str(&src).unwrap()); - }); -} - -fn bench_deserializer(b: &mut Bencher, count: usize) { - let src = json_str(count); - let json = encoder_json(count); - b.iter(|| { - assert_eq!(json, serialize::json::Json::from_str(&src).unwrap()); - }); -} - -fn bench_decoder_streaming(b: &mut Bencher, count: usize) { - let src = json_str(count); - - b.iter( || { - use rustc_serialize::json::{Parser, JsonEvent, StackElement}; - - let mut parser = Parser::new(src.chars()); - assert_eq!(parser.next(), Some(JsonEvent::ArrayStart)); - for _ in range(0, count) { - assert_eq!(parser.next(), Some(JsonEvent::ObjectStart)); - - assert_eq!(parser.next(), Some(JsonEvent::BooleanValue(true))); - assert_eq!(parser.stack().top(), Some(StackElement::Key("a"))); - - assert_eq!(parser.next(), Some(JsonEvent::NullValue)); - assert_eq!(parser.stack().top(), Some(StackElement::Key("b"))); - - assert_eq!(parser.next(), Some(JsonEvent::F64Value(3.1415))); - assert_eq!(parser.stack().top(), Some(StackElement::Key("c"))); - - assert_eq!(parser.next(), Some(JsonEvent::StringValue("Hello world".to_string()))); - assert_eq!(parser.stack().top(), Some(StackElement::Key("d"))); - - assert_eq!(parser.next(), Some(JsonEvent::ArrayStart)); - assert_eq!(parser.stack().top(), Some(StackElement::Key("e"))); - assert_eq!(parser.next(), Some(JsonEvent::U64Value(1))); - assert_eq!(parser.next(), Some(JsonEvent::U64Value(2))); - assert_eq!(parser.next(), Some(JsonEvent::U64Value(3))); - assert_eq!(parser.next(), Some(JsonEvent::ArrayEnd)); - - assert_eq!(parser.next(), Some(JsonEvent::ObjectEnd)); - } - assert_eq!(parser.next(), Some(JsonEvent::ObjectStart)); - assert_eq!(parser.next(), Some(JsonEvent::ObjectEnd)); - assert_eq!(parser.next(), Some(JsonEvent::ArrayEnd)); - assert_eq!(parser.next(), None); - }); -} - -fn bench_deserializer_streaming(b: &mut Bencher, count: usize) { - let src = json_str(count); - - b.iter( || { - let mut parser = Parser::new(src.bytes()); - - assert_eq!(parser.next(), Some(Ok(Token::SeqStart(0)))); - for _ in range(0, count) { - assert_eq!(parser.next(), Some(Ok(Token::MapStart(0)))); - - assert_eq!(parser.next(), Some(Ok(Token::String("a".to_string())))); - assert_eq!(parser.next(), Some(Ok(Token::Bool(true)))); - - assert_eq!(parser.next(), Some(Ok(Token::String("b".to_string())))); - assert_eq!(parser.next(), Some(Ok(Token::Null))); - - assert_eq!(parser.next(), Some(Ok(Token::String("c".to_string())))); - assert_eq!(parser.next(), Some(Ok(Token::F64(3.1415)))); - - assert_eq!(parser.next(), Some(Ok(Token::String("d".to_string())))); - assert_eq!(parser.next(), Some(Ok(Token::String("Hello world".to_string())))); - - assert_eq!(parser.next(), Some(Ok(Token::String("e".to_string())))); - assert_eq!(parser.next(), Some(Ok(Token::SeqStart(0)))); - assert_eq!(parser.next(), Some(Ok(Token::I64(1)))); - assert_eq!(parser.next(), Some(Ok(Token::I64(2)))); - assert_eq!(parser.next(), Some(Ok(Token::I64(3)))); - assert_eq!(parser.next(), Some(Ok(Token::End))); - - assert_eq!(parser.next(), Some(Ok(Token::End))); - } - assert_eq!(parser.next(), Some(Ok(Token::MapStart(0)))); - assert_eq!(parser.next(), Some(Ok(Token::End))); - assert_eq!(parser.next(), Some(Ok(Token::End))); - assert_eq!(parser.next(), None); - - loop { - match parser.next() { - None => return, - Some(Ok(_)) => { } - Some(Err(err)) => { panic!("error: {:?}", err); } - } - } - }); -} - -#[bench] -fn bench_encoder_001(b: &mut Bencher) { - bench_encoder(b, 1) -} - -#[bench] -fn bench_encoder_500(b: &mut Bencher) { - bench_encoder(b, 500) -} - -#[bench] -fn bench_encoder_001_pretty(b: &mut Bencher) { - bench_encoder_pretty(b, 1) -} - -#[bench] -fn bench_encoder_500_pretty(b: &mut Bencher) { - bench_encoder_pretty(b, 500) -} - -#[bench] -fn bench_serializer_001(b: &mut Bencher) { - bench_serializer(b, 1) -} - -#[bench] -fn bench_serializer_500(b: &mut Bencher) { - bench_serializer(b, 500) -} -#[bench] -fn bench_serializer_001_pretty(b: &mut Bencher) { - bench_serializer_pretty(b, 1) -} - -#[bench] -fn bench_serializer_500_pretty(b: &mut Bencher) { - bench_serializer_pretty(b, 500) -} - -#[bench] -fn bench_decoder_001(b: &mut Bencher) { - bench_decoder(b, 1) -} - -#[bench] -fn bench_decoder_500(b: &mut Bencher) { - bench_decoder(b, 500) -} - -#[bench] -fn bench_deserializer_001(b: &mut Bencher) { - bench_deserializer(b, 1) -} - -#[bench] -fn bench_deserializer_500(b: &mut Bencher) { - bench_deserializer(b, 500) -} - -#[bench] -fn bench_decoder_001_streaming(b: &mut Bencher) { - bench_decoder_streaming(b, 1) -} - -#[bench] -fn bench_decoder_500_streaming(b: &mut Bencher) { - bench_decoder_streaming(b, 500) -} - -#[bench] -fn bench_deserializer_001_streaming(b: &mut Bencher) { - bench_deserializer_streaming(b, 1) -} - -#[bench] -fn bench_deserializer_500_streaming(b: &mut Bencher) { - bench_deserializer_streaming(b, 500) -} diff --git a/serde2/.gitignore b/serde2/.gitignore deleted file mode 100644 index ca98cd96..00000000 --- a/serde2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target/ -Cargo.lock diff --git a/serde2/Cargo.toml b/serde2/Cargo.toml deleted file mode 100644 index f7fbd826..00000000 --- a/serde2/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "serde2" -version = "0.1.0" -authors = ["Erick Tryzelaar "] - -[lib] -name = "serde2" - -[dependencies] -rustc-serialize = "*" - -[dev-dependencies.serde2_macros] -path = "serde2_macros/" diff --git a/serde2/benches/bench_enum.rs b/serde2/benches/bench_enum.rs deleted file mode 100644 index 3a296f34..00000000 --- a/serde2/benches/bench_enum.rs +++ /dev/null @@ -1,417 +0,0 @@ -#![feature(custom_derive, plugin, test)] -#![plugin(serde2_macros)] - -extern crate serde2; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use test::Bencher; - -use rustc_serialize::{Decoder, Decodable}; - -use serde2::de::{Deserializer, Deserialize}; - -use Animal::{Dog, Frog}; - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug, RustcDecodable)] -#[derive_deserialize] -enum Animal { - Dog, - Frog(String, isize) -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Debug)] -pub enum Error { - EndOfStreamError, - SyntaxError, -} - -impl serde2::de::Error for Error { - fn syntax_error() -> Error { Error::SyntaxError } - - fn end_of_stream_error() -> Error { Error::EndOfStreamError } - - fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError } -} - -////////////////////////////////////////////////////////////////////////////// - -mod decoder { - use rustc_serialize::Decoder; - - use super::{Animal, Error}; - use super::Animal::{Dog, Frog}; - use self::State::{AnimalState, IsizeState, StringState}; - - enum State { - AnimalState(Animal), - IsizeState(isize), - StringState(String), - } - - pub struct AnimalDecoder { - stack: Vec, - - } - - impl AnimalDecoder { - #[inline] - pub fn new(animal: Animal) -> AnimalDecoder { - AnimalDecoder { - stack: vec!(AnimalState(animal)), - } - } - } - - impl Decoder for AnimalDecoder { - type Error = Error; - - fn error(&mut self, _: &str) -> Error { Error::SyntaxError } - - // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } - fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_isize(&mut self) -> Result { - match self.stack.pop() { - Some(IsizeState(x)) => Ok(x), - _ => Err(Error::SyntaxError), - } - } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_str(&mut self) -> Result { - match self.stack.pop() { - Some(StringState(x)) => Ok(x), - _ => Err(Error::SyntaxError), - } - } - - // Compound types: - #[inline] - fn read_enum(&mut self, name: &str, f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - match self.stack.pop() { - Some(AnimalState(animal)) => { - self.stack.push(AnimalState(animal)); - if name == "Animal" { - f(self) - } else { - Err(Error::SyntaxError) - } - } - _ => Err(Error::SyntaxError) - } - } - - #[inline] - fn read_enum_variant(&mut self, names: &[&str], f: F) -> Result where - F: FnOnce(&mut AnimalDecoder, usize) -> Result, - { - let name = match self.stack.pop() { - Some(AnimalState(Dog)) => "Dog", - Some(AnimalState(Frog(x0, x1))) => { - self.stack.push(IsizeState(x1)); - self.stack.push(StringState(x0)); - "Frog" - } - _ => { return Err(Error::SyntaxError); } - }; - - let idx = match names.iter().position(|n| *n == name) { - Some(idx) => idx, - None => { return Err(Error::SyntaxError); } - }; - - f(self, idx) - } - - #[inline] - fn read_enum_variant_arg(&mut self, _a_idx: usize, f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - f(self) - } - - fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - // Specialized types: - fn read_option(&mut self, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder, bool) -> Result, - { - Err(Error::SyntaxError) - } - - #[inline] - fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut AnimalDecoder, usize) -> Result, - { - f(self, 3) - } - - #[inline] - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - f(self) - } - - fn read_map(&mut self, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut AnimalDecoder) -> Result, - { - Err(Error::SyntaxError) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -mod deserializer { - use super::{Animal, Error}; - - use serde2::de; - - enum State { - AnimalState(Animal), - IsizeState(isize), - StringState(String), - UnitState, - } - - pub struct AnimalDeserializer { - stack: Vec, - } - - impl AnimalDeserializer { - #[inline] - pub fn new(animal: Animal) -> AnimalDeserializer { - AnimalDeserializer { - stack: vec!(State::AnimalState(animal)), - } - } - } - - impl de::Deserializer for AnimalDeserializer { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.stack.pop() { - Some(State::AnimalState(Animal::Dog)) => { - self.stack.push(State::UnitState); - visitor.visit_enum("Animal", "Dog", DogVisitor { - de: self, - }) - } - Some(State::AnimalState(Animal::Frog(x0, x1))) => { - self.stack.push(State::IsizeState(x1)); - self.stack.push(State::StringState(x0)); - visitor.visit_enum("Animal", "Frog", FrogVisitor { - de: self, - state: 0, - }) - } - Some(State::IsizeState(value)) => { - visitor.visit_isize(value) - } - Some(State::StringState(value)) => { - visitor.visit_string(value) - } - Some(State::UnitState) => { - visitor.visit_unit() - } - None => { - Err(Error::EndOfStreamError) - } - } - } - } - - struct DogVisitor<'a> { - de: &'a mut AnimalDeserializer, - } - - impl<'a> de::EnumVisitor for DogVisitor<'a> { - type Error = Error; - - fn visit_unit(&mut self) -> Result<(), Error> { - de::Deserialize::deserialize(self.de) - } - } - - struct FrogVisitor<'a> { - de: &'a mut AnimalDeserializer, - state: usize, - } - - impl<'a> de::EnumVisitor for FrogVisitor<'a> { - type Error = Error; - - fn visit_seq(&mut self, mut visitor: V) -> Result - where V: de::EnumSeqVisitor, - { - visitor.visit(self) - } - } - - impl<'a> de::SeqVisitor for FrogVisitor<'a> { - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize, - { - match self.state { - 0 => { - self.state += 1; - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - 1 => { - self.state += 1; - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - _ => { - Ok(None) - } - } - } - - fn end(&mut self) -> Result<(), Error> { - if self.state == 2 { - Ok(()) - } else { - Err(Error::SyntaxError) - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = 2 - self.state; - (len, Some(len)) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[bench] -fn bench_decoder_dog(b: &mut Bencher) { - b.iter(|| { - let animal = Dog; - - let mut d = decoder::AnimalDecoder::new(animal.clone()); - let value: Animal = Decodable::decode(&mut d).unwrap(); - - assert_eq!(value, animal); - }) -} - -#[bench] -fn bench_decoder_frog(b: &mut Bencher) { - b.iter(|| { - let animal = Frog("Henry".to_string(), 349); - - let mut d = decoder::AnimalDecoder::new(animal.clone()); - let value: Animal = Decodable::decode(&mut d).unwrap(); - - assert_eq!(value, animal); - }) -} - -#[bench] -fn bench_deserializer_dog(b: &mut Bencher) { - b.iter(|| { - let animal = Dog; - - let mut d = deserializer::AnimalDeserializer::new(animal.clone()); - let value: Animal = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, animal); - }) -} - -#[bench] -fn bench_deserializer_frog(b: &mut Bencher) { - b.iter(|| { - let animal = Frog("Henry".to_string(), 349); - - let mut d = deserializer::AnimalDeserializer::new(animal.clone()); - let value: Animal = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, animal); - }) -} diff --git a/serde2/benches/bench_log.rs b/serde2/benches/bench_log.rs deleted file mode 100644 index 7151db97..00000000 --- a/serde2/benches/bench_log.rs +++ /dev/null @@ -1,1212 +0,0 @@ -#![feature(custom_derive, collections, core, io, plugin, test)] -#![allow(non_camel_case_types)] -#![plugin(serde2_macros)] - -extern crate serde2; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use std::io::{self, ReadExt, WriteExt}; -use std::num::FromPrimitive; -use test::Bencher; - -use serde2::de::{self, Deserialize, Deserializer}; -use serde2::json::ser::escape_str; -use serde2::json; -use serde2::ser::{self, Serialize, Serializer}; - -use rustc_serialize::Encodable; - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)] -#[derive_serialize] -#[derive_deserialize] -struct Http { - protocol: HttpProtocol, - status: u32, - host_status: u32, - up_status: u32, - method: HttpMethod, - content_type: String, - user_agent: String, - referer: String, - request_uri: String, -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum HttpProtocol { - HTTP_PROTOCOL_UNKNOWN, - HTTP10, - HTTP11, -} - -impl rustc_serialize::Encodable for HttpProtocol { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as usize).encode(s) - } -} - -impl rustc_serialize::Decodable for HttpProtocol { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_usize(try!(d.read_usize())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from usize")), - } - } -} - -impl ser::Serialize for HttpProtocol { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for HttpProtocol { - #[inline] - fn deserialize< - S: Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum HttpMethod { - METHOD_UNKNOWN, - GET, - POST, - DELETE, - PUT, - HEAD, - PURGE, - OPTIONS, - PROPFIND, - MKCOL, - PATCH, -} - -impl rustc_serialize::Encodable for HttpMethod { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as usize).encode(s) - } -} - -impl rustc_serialize::Decodable for HttpMethod { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_usize(try!(d.read_usize())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from usize")), - } - } -} - -impl ser::Serialize for HttpMethod { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for HttpMethod { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum CacheStatus { - CACHESTATUS_UNKNOWN, - Miss, - Expired, - Hit, -} - -impl rustc_serialize::Encodable for CacheStatus { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for CacheStatus { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for CacheStatus { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for CacheStatus { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)] -#[derive_serialize] -#[derive_deserialize] -struct Origin { - ip: String, - port: u32, - hostname: String, - protocol: OriginProtocol, -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum OriginProtocol { - ORIGIN_PROTOCOL_UNKNOWN, - HTTP, - HTTPS, -} - -impl rustc_serialize::Encodable for OriginProtocol { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for OriginProtocol { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for OriginProtocol { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for OriginProtocol { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum ZonePlan { - ZONEPLAN_UNKNOWN, - FREE, - PRO, - BIZ, - ENT, -} - -impl rustc_serialize::Encodable for ZonePlan { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for ZonePlan { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for ZonePlan { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for ZonePlan { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Copy, Debug, PartialEq, FromPrimitive)] -enum Country { - UNKNOWN, - A1, - A2, - O1, - AD, - AE, - AF, - AG, - AI, - AL, - AM, - AO, - AP, - AQ, - AR, - AS, - AT, - AU, - AW, - AX, - AZ, - BA, - BB, - BD, - BE, - BF, - BG, - BH, - BI, - BJ, - BL, - BM, - BN, - BO, - BQ, - BR, - BS, - BT, - BV, - BW, - BY, - BZ, - CA, - CC, - CD, - CF, - CG, - CH, - CI, - CK, - CL, - CM, - CN, - CO, - CR, - CU, - CV, - CW, - CX, - CY, - CZ, - DE, - DJ, - DK, - DM, - DO, - DZ, - EC, - EE, - EG, - EH, - ER, - ES, - ET, - EU, - FI, - FJ, - FK, - FM, - FO, - FR, - GA, - GB, - GD, - GE, - GF, - GG, - GH, - GI, - GL, - GM, - GN, - GP, - GQ, - GR, - GS, - GT, - GU, - GW, - GY, - HK, - HM, - HN, - HR, - HT, - HU, - ID, - IE, - IL, - IM, - IN, - IO, - IQ, - IR, - IS, - IT, - JE, - JM, - JO, - JP, - KE, - KG, - KH, - KI, - KM, - KN, - KP, - KR, - KW, - KY, - KZ, - LA, - LB, - LC, - LI, - LK, - LR, - LS, - LT, - LU, - LV, - LY, - MA, - MC, - MD, - ME, - MF, - MG, - MH, - MK, - ML, - MM, - MN, - MO, - MP, - MQ, - MR, - MS, - MT, - MU, - MV, - MW, - MX, - MY, - MZ, - NA, - NC, - NE, - NF, - NG, - NI, - NL, - NO, - NP, - NR, - NU, - NZ, - OM, - PA, - PE, - PF, - PG, - PH, - PK, - PL, - PM, - PN, - PR, - PS, - PT, - PW, - PY, - QA, - RE, - RO, - RS, - RU, - RW, - SA, - SB, - SC, - SD, - SE, - SG, - SH, - SI, - SJ, - SK, - SL, - SM, - SN, - SO, - SR, - SS, - ST, - SV, - SX, - SY, - SZ, - TC, - TD, - TF, - TG, - TH, - TJ, - TK, - TL, - TM, - TN, - TO, - TR, - TT, - TV, - TW, - TZ, - UA, - UG, - UM, - US, - UY, - UZ, - VA, - VC, - VE, - VG, - VI, - VN, - VU, - WF, - WS, - XX, - YE, - YT, - ZA, - ZM, - ZW, -} - -impl rustc_serialize::Encodable for Country { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (*self as u8).encode(s) - } -} - -impl rustc_serialize::Decodable for Country { - fn decode(d: &mut D) -> Result { - match FromPrimitive::from_u8(try!(d.read_u8())) { - Some(value) => Ok(value), - None => Err(d.error("cannot convert from u8")), - } - } -} - -impl ser::Serialize for Country { - #[inline] - fn visit< - V: ser::Visitor, - >(&self, visitor: &mut V) -> Result { - visitor.visit_u8(*self as u8) - } -} - -impl de::Deserialize for Country { - #[inline] - fn deserialize< - S: de::Deserializer, - >(state: &mut S) -> Result { - state.visit(de::PrimitiveVisitor::new()) - } -} - -#[derive(Debug, PartialEq, RustcEncodable, RustcDecodable)] -#[derive_serialize] -#[derive_deserialize] -struct Log { - timestamp: i64, - zone_id: u32, - zone_plan: ZonePlan, - http: Http, - origin: Origin, - country: Country, - cache_status: CacheStatus, - server_ip: String, - server_name: String, - remote_ip: String, - bytes_dlv: u64, - ray_id: String, -} - -impl Log { - fn new() -> Log { - Log { - timestamp: 2837513946597, - zone_id: 123456, - zone_plan: ZonePlan::FREE, - http: Http { - protocol: HttpProtocol::HTTP11, - status: 200, - host_status: 503, - up_status: 520, - method: HttpMethod::GET, - content_type: "text/html".to_string(), - user_agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36".to_string(), - referer: "https://www.cloudflare.com/".to_string(), - request_uri: "/cdn-cgi/trace".to_string(), - }, - origin: Origin { - ip: "1.2.3.4".to_string(), - port: 8000, - hostname: "www.example.com".to_string(), - protocol: OriginProtocol::HTTPS, - }, - country: Country::US, - cache_status: CacheStatus::Hit, - server_ip: "192.168.1.1".to_string(), - server_name: "metal.cloudflare.com".to_string(), - remote_ip: "10.1.2.3".to_string(), - bytes_dlv: 123456, - ray_id: "10c73629cce30078-LAX".to_string(), - } - } -} - -macro_rules! likely( - ($val:expr) => { - { - extern { - #[link_name = "llvm.expect.i8"] - fn expect(val: u8, expected_val: u8) -> u8; - } - let x: bool = $val; - unsafe { expect(x as u8, 1) != 0 } - } - } -); - -macro_rules! unlikely( - ($val:expr) => { - { - extern { - #[link_name = "llvm.expect.i8"] - fn expect(val: u8, expected_val: u8) -> u8; - } - let x: bool = $val; - unsafe { expect(x as u8, 0) != 0 } - } - } -); - -struct MyMemWriter0 { - buf: Vec, -} - -impl MyMemWriter0 { - pub fn with_capacity(cap: usize) -> MyMemWriter0 { - MyMemWriter0 { - buf: Vec::with_capacity(cap) - } - } -} - - -impl io::Write for MyMemWriter0 { - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - self.buf.push_all(buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -struct MyMemWriter1 { - buf: Vec, -} - -impl MyMemWriter1 { - pub fn with_capacity(cap: usize) -> MyMemWriter1 { - MyMemWriter1 { - buf: Vec::with_capacity(cap) - } - } -} - -// LLVM isn't yet able to lower `Vec::push_all` into a memcpy, so this helps -// MemWriter eke out that last bit of performance. -#[inline] -fn push_all_bytes(dst: &mut Vec, src: &[u8]) { - let dst_len = dst.len(); - let src_len = src.len(); - - dst.reserve(src_len); - - unsafe { - // we would have failed if `reserve` overflowed. - dst.set_len(dst_len + src_len); - - ::std::ptr::copy_nonoverlapping( - dst.as_mut_ptr().offset(dst_len as isize), - src.as_ptr(), - src_len); - } -} - -impl io::Write for MyMemWriter1 { - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - push_all_bytes(&mut self.buf, buf); - Ok(buf.len()) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -const JSON_STR: &'static str = r#"{"timestamp":2837513946597,"zone_id":123456,"zone_plan":1,"http":{"protocol":2,"status":200,"host_status":503,"up_status":520,"method":1,"content_type":"text/html","user_agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36","referer":"https://www.cloudflare.com/","request_uri":"/cdn-cgi/trace"},"origin":{"ip":"1.2.3.4","port":8000,"hostname":"www.example.com","protocol":2},"country":238,"cache_status":3,"server_ip":"192.168.1.1","server_name":"metal.cloudflare.com","remote_ip":"10.1.2.3","bytes_dlv":123456,"ray_id":"10c73629cce30078-LAX"}"#; - -#[test] -fn test_encoder() { - use rustc_serialize::Encodable; - - let log = Log::new(); - - let mut wr = String::with_capacity(1024); - - { - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap(); - } - - assert_eq!(&wr, &JSON_STR); -} - -#[bench] -fn bench_encoder(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = String::with_capacity(1024); - - { - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap(); - } - - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - - let mut encoder = rustc_serialize::json::Encoder::new(&mut wr); - log.encode(&mut encoder).unwrap(); - }); -} - -#[test] -fn test_serializer() { - let log = Log::new(); - let json = json::to_vec(&log); - assert_eq!(json, JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer(b: &mut Bencher) { - let log = Log::new(); - let json = json::to_vec(&log); - b.bytes = json.len() as u64; - - b.iter(|| { - let _ = json::to_vec(&log); - }); -} - -#[test] -fn test_serializer_vec() { - let log = Log::new(); - let wr = Vec::with_capacity(1024); - let mut serializer = json::Serializer::new(wr); - serializer.visit(&log).unwrap(); - - let json = serializer.into_inner(); - assert_eq!(&json, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_vec(b: &mut Bencher) { - let log = Log::new(); - let json = json::to_vec(&log); - b.bytes = json.len() as u64; - - let mut wr = Vec::with_capacity(1024); - - b.iter(|| { - wr.clear(); - - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - }); -} - -#[bench] -fn bench_serializer_slice(b: &mut Bencher) { - let log = Log::new(); - let json = json::to_vec(&log); - b.bytes = json.len() as u64; - - let mut buf = [0; 1024]; - - b.iter(|| { - for item in buf.iter_mut(){ *item = 0; } - let mut wr = &mut buf[..]; - - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - }); -} - -#[test] -fn test_serializer_my_mem_writer0() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - - { - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - } - - assert_eq!(&wr.buf, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_my_mem_writer0(b: &mut Bencher) { - let log = Log::new(); - let json = json::to_vec(&log); - b.bytes = json.len() as u64; - - let mut wr = MyMemWriter0::with_capacity(1024); - - b.iter(|| { - wr.buf.clear(); - - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - }); -} - -#[test] -fn test_serializer_my_mem_writer1() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - - { - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - } - - assert_eq!(&wr.buf, &JSON_STR.as_bytes()); -} - -#[bench] -fn bench_serializer_my_mem_writer1(b: &mut Bencher) { - let log = Log::new(); - let json = json::to_vec(&log); - b.bytes = json.len() as u64; - - let mut wr = MyMemWriter1::with_capacity(1024); - - b.iter(|| { - wr.buf.clear(); - - let mut serializer = json::Serializer::new(wr.by_ref()); - serializer.visit(&log).unwrap(); - let _json = serializer.into_inner(); - }); -} - -#[bench] -fn bench_copy(b: &mut Bencher) { - let json = JSON_STR.as_bytes().to_vec(); - b.bytes = json.len() as u64; - - b.iter(|| { - let _json = JSON_STR.as_bytes().to_vec(); - }); -} - -fn manual_serialize_no_escape(wr: &mut W, log: &Log) { - wr.write(b"{\"timestamp\":").unwrap(); - (write!(wr, "{}", log.timestamp)).unwrap(); - wr.write(b",\"zone_id\":").unwrap(); - (write!(wr, "{}", log.zone_id)).unwrap(); - wr.write(b",\"zone_plan\":").unwrap(); - (write!(wr, "{}", log.zone_plan as usize)).unwrap(); - - wr.write(b",\"http\":{\"protocol\":").unwrap(); - (write!(wr, "{}", log.http.protocol as usize)).unwrap(); - wr.write(b",\"status\":").unwrap(); - (write!(wr, "{}", log.http.status)).unwrap(); - wr.write(b",\"host_status\":").unwrap(); - (write!(wr, "{}", log.http.host_status)).unwrap(); - wr.write(b",\"up_status\":").unwrap(); - (write!(wr, "{}", log.http.up_status)).unwrap(); - wr.write(b",\"method\":").unwrap(); - (write!(wr, "{}", log.http.method as usize)).unwrap(); - wr.write(b",\"content_type\":").unwrap(); - (write!(wr, "\"{}\"", log.http.content_type)).unwrap(); - wr.write(b",\"user_agent\":").unwrap(); - (write!(wr, "\"{}\"", log.http.user_agent)).unwrap(); - wr.write(b",\"referer\":").unwrap(); - (write!(wr, "\"{}\"", log.http.referer)).unwrap(); - wr.write(b",\"request_uri\":").unwrap(); - (write!(wr, "\"{}\"", log.http.request_uri)).unwrap(); - - wr.write(b"},\"origin\":{").unwrap(); - - wr.write(b"\"ip\":").unwrap(); - (write!(wr, "\"{}\"", log.origin.ip)).unwrap(); - wr.write(b",\"port\":").unwrap(); - (write!(wr, "{}", log.origin.port)).unwrap(); - wr.write(b",\"hostname\":").unwrap(); - (write!(wr, "\"{}\"", log.origin.hostname)).unwrap(); - - wr.write(b",\"protocol\":").unwrap(); - (write!(wr, "{}", log.origin.protocol as usize)).unwrap(); - - wr.write(b"},\"country\":").unwrap(); - (write!(wr, "{}", log.country as usize)).unwrap(); - wr.write(b",\"cache_status\":").unwrap(); - (write!(wr, "{}", log.cache_status as usize)).unwrap(); - wr.write(b",\"server_ip\":").unwrap(); - (write!(wr, "\"{}\"", log.server_ip)).unwrap(); - wr.write(b",\"server_name\":").unwrap(); - (write!(wr, "\"{}\"", log.server_name)).unwrap(); - wr.write(b",\"remote_ip\":").unwrap(); - (write!(wr, "\"{}\"", log.remote_ip)).unwrap(); - wr.write(b",\"bytes_dlv\":").unwrap(); - (write!(wr, "{}", log.bytes_dlv)).unwrap(); - - wr.write(b",\"ray_id\":").unwrap(); - (write!(wr, "\"{}\"", log.ray_id)).unwrap(); - wr.write(b"}").unwrap(); -} - -fn manual_serialize_escape(wr: &mut W, log: &Log) { - wr.write_all(b"{").unwrap(); - escape_str(wr, "timestamp").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.timestamp)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "zone_id").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.zone_id)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "zone_plan").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.zone_plan as isize)).unwrap(); - - wr.write_all(b",").unwrap(); - escape_str(wr, "http").unwrap(); - wr.write_all(b":{").unwrap(); - escape_str(wr, "protocol").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.protocol as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "host_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.host_status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "up_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.up_status)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "method").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.http.method as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "content_type").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.content_type).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "user_agent").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.user_agent).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "referer").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.referer).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "request_uri").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.http.request_uri).unwrap(); - - wr.write_all(b"},").unwrap(); - escape_str(wr, "origin").unwrap(); - wr.write_all(b":{").unwrap(); - - escape_str(wr, "ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.origin.ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "port").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.origin.port)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "hostname").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.origin.hostname).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "protocol").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.origin.protocol as usize)).unwrap(); - - wr.write_all(b"},").unwrap(); - escape_str(wr, "country").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.country as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "cache_status").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.cache_status as usize)).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "server_ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.server_ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "server_name").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.server_name).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "remote_ip").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.remote_ip).unwrap(); - wr.write_all(b",").unwrap(); - escape_str(wr, "bytes_dlv").unwrap(); - wr.write_all(b":").unwrap(); - (write!(wr, "{}", log.bytes_dlv)).unwrap(); - - wr.write_all(b",").unwrap(); - escape_str(wr, "ray_id").unwrap(); - wr.write_all(b":").unwrap(); - escape_str(wr, &log.ray_id).unwrap(); - wr.write_all(b"}").unwrap(); -} - -#[test] -fn test_manual_serialize_vec_no_escape() { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_vec_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - manual_serialize_no_escape(&mut wr, &log); - }); -} - -#[test] -fn test_manual_serialize_vec_escape() { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_vec_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = Vec::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.len() as u64; - - b.iter(|| { - wr.clear(); - - manual_serialize_escape(&mut wr, &log); - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer0_no_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1000); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer0_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_no_escape(&mut wr, &log); - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer0_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer0_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter0::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_escape(&mut wr, &log); - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer1_no_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer1_no_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_no_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_no_escape(&mut wr, &log); - }); -} - -#[test] -fn test_manual_serialize_my_mem_writer1_escape() { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - - let json = String::from_utf8(wr.buf).unwrap(); - assert_eq!(&JSON_STR, &json); -} - -#[bench] -fn bench_manual_serialize_my_mem_writer1_escape(b: &mut Bencher) { - let log = Log::new(); - - let mut wr = MyMemWriter1::with_capacity(1024); - manual_serialize_escape(&mut wr, &log); - b.bytes = wr.buf.len() as u64; - - b.iter(|| { - wr.buf.clear(); - - manual_serialize_escape(&mut wr, &log); - }); -} - -#[bench] -fn bench_decoder(b: &mut Bencher) { - use rustc_serialize::json::Json; - - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let json = Json::from_str(JSON_STR).unwrap(); - let mut decoder = rustc_serialize::json::Decoder::new(json); - let _log: Log = rustc_serialize::Decodable::decode(&mut decoder).unwrap(); - }); -} - -#[bench] -fn bench_deserializer(b: &mut Bencher) { - b.bytes = JSON_STR.len() as u64; - - b.iter(|| { - let _log: Log = json::from_str(JSON_STR).unwrap(); - }); -} diff --git a/serde2/benches/bench_map.rs b/serde2/benches/bench_map.rs deleted file mode 100644 index 57bf6b8d..00000000 --- a/serde2/benches/bench_map.rs +++ /dev/null @@ -1,462 +0,0 @@ -#![feature(custom_derive, core, plugin, test)] -#![plugin(serde2_macros)] - -extern crate serde2; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use std::fmt::Debug; -use std::collections::HashMap; -use test::Bencher; - -use rustc_serialize::{Decoder, Decodable}; - -use serde2::de::{Deserializer, Deserialize}; - -////////////////////////////////////////////////////////////////////////////// - -#[derive(PartialEq, Debug)] -pub enum Error { - EndOfStream, - SyntaxError, - MissingField, -} - -impl serde2::de::Error for Error { - fn syntax_error() -> Error { Error::SyntaxError } - - fn end_of_stream_error() -> Error { Error::EndOfStream } - - fn missing_field_error(_: &'static str) -> Error { - Error::MissingField - } -} - -////////////////////////////////////////////////////////////////////////////// - -mod decoder { - use std::collections::HashMap; - use std::collections::hash_map::IntoIter; - use rustc_serialize; - - use super::Error; - use self::Value::{StringValue, IsizeValue}; - - enum Value { - StringValue(String), - IsizeValue(isize), - } - - pub struct IsizeDecoder { - len: usize, - iter: IntoIter, - stack: Vec, - } - - impl IsizeDecoder { - #[inline] - pub fn new(values: HashMap) -> IsizeDecoder { - IsizeDecoder { - len: values.len(), - iter: values.into_iter(), - stack: vec!(), - } - } - } - - impl rustc_serialize::Decoder for IsizeDecoder { - type Error = Error; - - fn error(&mut self, _msg: &str) -> Error { - Error::SyntaxError - } - - // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } - fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_isize(&mut self) -> Result { - match self.stack.pop() { - Some(IsizeValue(x)) => Ok(x), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStream), - } - } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_str(&mut self) -> Result { - match self.stack.pop() { - Some(StringValue(x)) => Ok(x), - Some(_) => Err(Error::SyntaxError), - None => Err(Error::EndOfStream), - } - } - - // Compound types: - fn read_enum(&mut self, _name: &str, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - // Specialized types: - fn read_option(&mut self, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, bool) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_seq(&mut self, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_seq_elt(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - #[inline] - fn read_map(&mut self, f: F) -> Result where - F: FnOnce(&mut IsizeDecoder, usize) -> Result, - { - let len = self.len; - f(self, len) - } - #[inline] - fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - match self.iter.next() { - Some((key, value)) => { - self.stack.push(IsizeValue(value)); - self.stack.push(StringValue(key)); - f(self) - } - None => { - Err(Error::SyntaxError) - } - } - } - - #[inline] - fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut IsizeDecoder) -> Result, - { - f(self) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -mod deserializer { - use std::collections::HashMap; - use std::collections::hash_map; - - use super::Error; - - use serde2::de; - - #[derive(PartialEq, Debug)] - enum State { - StartState, - KeyState(String), - ValueState(isize), - } - - pub struct IsizeDeserializer { - stack: Vec, - iter: hash_map::IntoIter, - } - - impl IsizeDeserializer { - #[inline] - pub fn new(values: HashMap) -> IsizeDeserializer { - IsizeDeserializer { - stack: vec!(State::StartState), - iter: values.into_iter(), - } - } - } - - impl de::Deserializer for IsizeDeserializer { - type Error = Error; - - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.stack.pop() { - Some(State::StartState) => { - visitor.visit_map(self) - } - Some(State::KeyState(key)) => { - visitor.visit_string(key) - } - Some(State::ValueState(value)) => { - visitor.visit_isize(value) - } - None => { - Err(Error::EndOfStream) - } - } - } - } - - impl de::MapVisitor for IsizeDeserializer { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: de::Deserialize, - { - match self.iter.next() { - Some((key, value)) => { - self.stack.push(State::ValueState(value)); - self.stack.push(State::KeyState(key)); - Ok(Some(try!(de::Deserialize::deserialize(self)))) - } - None => { - Ok(None) - } - } - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(self) - } - - fn end(&mut self) -> Result<(), Error> { - match self.iter.next() { - Some(_) => Err(Error::SyntaxError), - None => Ok(()), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - } - -/* - impl Iterator for IsizeDeserializer { - type Item = Result; - - #[inline] - fn next(&mut self) -> Option> { - match self.stack.pop() { - Some(StartState) => { - self.stack.push(KeyOrEndState); - Some(Ok(de::Token::MapStart(self.len))) - } - Some(KeyOrEndState) => { - match self.iter.next() { - Some((key, value)) => { - self.stack.push(ValueState(value)); - Some(Ok(de::Token::String(key))) - } - None => { - self.stack.push(EndState); - Some(Ok(de::Token::End)) - } - } - } - Some(ValueState(x)) => { - self.stack.push(KeyOrEndState); - Some(Ok(de::Token::Isize(x))) - } - Some(EndState) => { - None - } - None => { - None - } - } - } - } - - impl de::Deserializer for IsizeDeserializer { - #[inline] - fn end_of_stream_error(&mut self) -> Error { - EndOfStream - } - - #[inline] - fn syntax_error(&mut self, _token: de::Token, _expected: &[de::TokenKind]) -> Error { - SyntaxError - } - - #[inline] - fn unexpected_name_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn conversion_error(&mut self, _token: de::Token) -> Error { - SyntaxError - } - - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, _field: &'static str) -> Result { - Err(Error::SyntaxError) - } - } -*/ -} - -////////////////////////////////////////////////////////////////////////////// - -fn run_decoder< - D: Decoder, - T: Clone + PartialEq + Debug + Decodable ->(mut d: D, value: T) { - let v = Decodable::decode(&mut d); - - assert_eq!(Ok(value), v); -} - -#[bench] -fn bench_decoder_000(b: &mut Bencher) { - b.iter(|| { - let m: HashMap = HashMap::new(); - run_decoder(decoder::IsizeDecoder::new(m.clone()), m) - }) -} - -#[bench] -fn bench_decoder_003(b: &mut Bencher) { - b.iter(|| { - let mut m: HashMap = HashMap::new(); - for i in range(0, 3) { - m.insert(i.to_string(), i); - } - run_decoder(decoder::IsizeDecoder::new(m.clone()), m) - }) -} - -#[bench] -fn bench_decoder_100(b: &mut Bencher) { - b.iter(|| { - let mut m: HashMap = HashMap::new(); - for i in range(0, 100) { - m.insert(i.to_string(), i); - } - run_decoder(decoder::IsizeDecoder::new(m.clone()), m) - }) -} - -fn run_deserializer< - D: Deserializer, - E: Debug, - T: Clone + PartialEq + Debug + Deserialize ->(mut d: D, value: T) { - let v: T = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, v); -} - -#[bench] -fn bench_deserializer_000(b: &mut Bencher) { - b.iter(|| { - let m: HashMap = HashMap::new(); - run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) - }) -} - -#[bench] -fn bench_deserializer_003(b: &mut Bencher) { - b.iter(|| { - let mut m: HashMap = HashMap::new(); - for i in range(0, 3) { - m.insert(i.to_string(), i); - } - run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) - }) -} - -#[bench] -fn bench_deserializer_100(b: &mut Bencher) { - b.iter(|| { - let mut m: HashMap = HashMap::new(); - for i in range(0, 100) { - m.insert(i.to_string(), i); - } - run_deserializer(deserializer::IsizeDeserializer::new(m.clone()), m) - }) -} diff --git a/serde2/benches/bench_struct.rs b/serde2/benches/bench_struct.rs deleted file mode 100644 index c3e5a6ab..00000000 --- a/serde2/benches/bench_struct.rs +++ /dev/null @@ -1,726 +0,0 @@ -#![feature(custom_derive, plugin, test)] -#![plugin(serde2_macros)] - -extern crate serde2; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use std::collections::HashMap; -use test::Bencher; - -use rustc_serialize::{Decoder, Decodable}; - -use serde2::de::{Deserializer, Deserialize}; - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug, RustcDecodable)] -#[derive_deserialize] -struct Inner { - a: (), - b: usize, - c: HashMap>, -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug, RustcDecodable)] -#[derive_deserialize] -struct Outer { - inner: Vec, -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Debug)] -pub enum Error { - EndOfStream, - SyntaxError, - UnexpectedName, - ConversionError, - MissingField, - OtherError, -} - -impl serde2::de::Error for Error { - fn syntax_error() -> Error { Error::SyntaxError } - - fn end_of_stream_error() -> Error { Error::EndOfStream } - - fn missing_field_error(_: &'static str) -> Error { - Error::MissingField - } -} - -mod decoder { - use std::collections::HashMap; - use rustc_serialize::Decoder; - - use super::{Outer, Inner, Error}; - - use self::State::{ - OuterState, - InnerState, - NullState, - UsizeState, - CharState, - StringState, - FieldState, - VecState, - MapState, - OptionState, - }; - - #[derive(Debug)] - enum State { - OuterState(Outer), - InnerState(Inner), - NullState, - UsizeState(usize), - CharState(char), - StringState(String), - FieldState(&'static str), - VecState(Vec), - MapState(HashMap>), - OptionState(bool), - } - - pub struct OuterDecoder { - stack: Vec, - - } - - impl OuterDecoder { - #[inline] - pub fn new(animal: Outer) -> OuterDecoder { - OuterDecoder { - stack: vec!(OuterState(animal)), - } - } - } - - impl Decoder for OuterDecoder { - type Error = Error; - - fn error(&mut self, _msg: &str) -> Error { - Error::OtherError - } - - // Primitive types: - #[inline] - fn read_nil(&mut self) -> Result<(), Error> { - match self.stack.pop() { - Some(NullState) => Ok(()), - _ => Err(Error::SyntaxError), - } - } - #[inline] - fn read_usize(&mut self) -> Result { - match self.stack.pop() { - Some(UsizeState(value)) => Ok(value), - _ => Err(Error::SyntaxError), - } - } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_char(&mut self) -> Result { - match self.stack.pop() { - Some(CharState(c)) => Ok(c), - _ => Err(Error::SyntaxError), - } - } - #[inline] - fn read_str(&mut self) -> Result { - match self.stack.pop() { - Some(StringState(value)) => Ok(value), - _ => Err(Error::SyntaxError), - } - } - - // Compound types: - fn read_enum(&mut self, _name: &str, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut OuterDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut OuterDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - #[inline] - fn read_struct(&mut self, s_name: &str, _len: usize, f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - match self.stack.pop() { - Some(OuterState(Outer { inner })) => { - if s_name == "Outer" { - self.stack.push(VecState(inner)); - self.stack.push(FieldState("inner")); - f(self) - } else { - Err(Error::SyntaxError) - } - } - Some(InnerState(Inner { a: (), b, c })) => { - if s_name == "Inner" { - self.stack.push(MapState(c)); - self.stack.push(FieldState("c")); - - self.stack.push(UsizeState(b)); - self.stack.push(FieldState("b")); - - self.stack.push(NullState); - self.stack.push(FieldState("a")); - f(self) - } else { - Err(Error::SyntaxError) - } - } - _ => Err(Error::SyntaxError), - } - } - #[inline] - fn read_struct_field(&mut self, f_name: &str, _f_idx: usize, f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - match self.stack.pop() { - Some(FieldState(name)) => { - if f_name == name { - f(self) - } else { - Err(Error::SyntaxError) - } - } - _ => Err(Error::SyntaxError) - } - } - - fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - // Specialized types: - #[inline] - fn read_option(&mut self, f: F) -> Result where - F: FnOnce(&mut OuterDecoder, bool) -> Result, - { - match self.stack.pop() { - Some(OptionState(b)) => f(self, b), - _ => Err(Error::SyntaxError), - } - } - - #[inline] - fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut OuterDecoder, usize) -> Result, - { - match self.stack.pop() { - Some(VecState(value)) => { - let len = value.len(); - for inner in value.into_iter().rev() { - self.stack.push(InnerState(inner)); - } - f(self, len) - } - _ => Err(Error::SyntaxError) - } - } - #[inline] - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - f(self) - } - - #[inline] - fn read_map(&mut self, f: F) -> Result where - F: FnOnce(&mut OuterDecoder, usize) -> Result, - { - match self.stack.pop() { - Some(MapState(map)) => { - let len = map.len(); - for (key, value) in map { - match value { - Some(c) => { - self.stack.push(CharState(c)); - self.stack.push(OptionState(true)); - } - None => { - self.stack.push(OptionState(false)); - } - } - self.stack.push(StringState(key)); - } - f(self, len) - } - _ => Err(Error::SyntaxError), - } - } - #[inline] - fn read_map_elt_key(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - f(self) - } - - #[inline] - fn read_map_elt_val(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut OuterDecoder) -> Result, - { - f(self) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -mod deserializer { - use std::collections::HashMap; - use std::collections::hash_map; - use std::vec; - use super::{Outer, Inner}; - use super::Error; - use serde2::de; - - #[derive(Debug)] - enum State { - OuterState(Outer), - InnerState(Inner), - StrState(&'static str), - NullState, - UsizeState(usize), - CharState(char), - StringState(String), - OptionState(bool), - VecState(Vec), - MapState(HashMap>), - } - - pub struct OuterDeserializer { - stack: Vec, - } - - impl OuterDeserializer { - #[inline] - pub fn new(outer: Outer) -> OuterDeserializer { - OuterDeserializer { - stack: vec!(State::OuterState(outer)), - } - } - } - - impl de::Deserializer for OuterDeserializer { - type Error = Error; - - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.stack.pop() { - Some(State::OuterState(Outer { inner })) => { - self.stack.push(State::VecState(inner)); - self.stack.push(State::StrState("inner")); - - visitor.visit_named_map("Outer", OuterMapVisitor { - de: self, - state: 0, - }) - } - Some(State::InnerState(Inner { a: (), b, c })) => { - self.stack.push(State::MapState(c)); - self.stack.push(State::StrState("c")); - - self.stack.push(State::UsizeState(b)); - self.stack.push(State::StrState("b")); - - self.stack.push(State::NullState); - self.stack.push(State::StrState("a")); - - visitor.visit_named_map("Inner", InnerMapVisitor { - de: self, - state: 0, - }) - } - Some(State::VecState(value)) => { - visitor.visit_seq(OuterSeqVisitor { - de: self, - iter: value.into_iter(), - }) - } - Some(State::MapState(value)) => { - visitor.visit_map(MapVisitor { - de: self, - iter: value.into_iter(), - }) - } - Some(State::NullState) => { - visitor.visit_unit() - } - Some(State::UsizeState(x)) => { - visitor.visit_usize(x) - } - Some(State::CharState(x)) => { - visitor.visit_char(x) - } - Some(State::StrState(x)) => { - visitor.visit_str(x) - } - Some(State::StringState(x)) => { - visitor.visit_string(x) - } - Some(State::OptionState(false)) => { - visitor.visit_none() - } - Some(State::OptionState(true)) => { - visitor.visit_some(self) - } - None => Err(Error::EndOfStream), - } - } - } - - struct OuterMapVisitor<'a> { - de: &'a mut OuterDeserializer, - state: usize, - } - - impl<'a> de::MapVisitor for OuterMapVisitor<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: de::Deserialize, - { - match self.state { - 0 => { - self.state += 1; - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - _ => { - Ok(None) - } - } - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(self.de) - } - - fn end(&mut self) -> Result<(), Error> { - if self.state == 1 { - Ok(()) - } else { - Err(Error::SyntaxError) - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = 1 - self.state; - (len, Some(len)) - } - } - - struct OuterSeqVisitor<'a> { - de: &'a mut OuterDeserializer, - iter: vec::IntoIter, - } - - impl<'a> de::SeqVisitor for OuterSeqVisitor<'a> { - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize, - { - match self.iter.next() { - Some(value) => { - self.de.stack.push(State::InnerState(value)); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => { - Ok(None) - } - } - } - - fn end(&mut self) -> Result<(), Error> { - match self.iter.next() { - Some(_) => Err(Error::SyntaxError), - None => Ok(()), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - } - - struct InnerMapVisitor<'a> { - de: &'a mut OuterDeserializer, - state: usize, - } - - impl<'a> de::MapVisitor for InnerMapVisitor<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: de::Deserialize, - { - match self.state { - 0 ... 2 => { - self.state += 1; - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - _ => { - Ok(None) - } - } - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(self.de) - } - - fn end(&mut self) -> Result<(), Error> { - if self.state == 1 { - Ok(()) - } else { - Err(Error::SyntaxError) - } - } - - fn size_hint(&self) -> (usize, Option) { - let len = 1 - self.state; - (len, Some(len)) - } - } - - struct MapVisitor<'a> { - de: &'a mut OuterDeserializer, - iter: hash_map::IntoIter>, - } - - impl<'a> de::MapVisitor for MapVisitor<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: de::Deserialize, - { - match self.iter.next() { - Some((key, Some(value))) => { - self.de.stack.push(State::CharState(value)); - self.de.stack.push(State::OptionState(true)); - self.de.stack.push(State::StringState(key)); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - Some((key, None)) => { - self.de.stack.push(State::OptionState(false)); - self.de.stack.push(State::StringState(key)); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => { - Ok(None) - } - } - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - de::Deserialize::deserialize(self.de) - } - - fn end(&mut self) -> Result<(), Error> { - match self.iter.next() { - Some(_) => Err(Error::SyntaxError), - None => Ok(()), - } - } - - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - } -} - -#[bench] -fn bench_decoder_0_0(b: &mut Bencher) { - b.iter(|| { - let mut map = HashMap::new(); - map.insert("abc".to_string(), Some('c')); - - let outer = Outer { - inner: vec!(), - }; - - let mut d = decoder::OuterDecoder::new(outer.clone()); - let value: Outer = Decodable::decode(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} - -#[bench] -fn bench_decoder_1_0(b: &mut Bencher) { - b.iter(|| { - let map = HashMap::new(); - - let outer = Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: map, - }, - ) - }; - - let mut d = decoder::OuterDecoder::new(outer.clone()); - let value: Outer = Decodable::decode(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} - -#[bench] -fn bench_decoder_1_5(b: &mut Bencher) { - b.iter(|| { - let mut map = HashMap::new(); - map.insert("1".to_string(), Some('a')); - map.insert("2".to_string(), None); - map.insert("3".to_string(), Some('b')); - map.insert("4".to_string(), None); - map.insert("5".to_string(), Some('c')); - - let outer = Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: map, - }, - ) - }; - - let mut d = decoder::OuterDecoder::new(outer.clone()); - let value: Outer = Decodable::decode(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} - -#[bench] -fn bench_deserializer_0_0(b: &mut Bencher) { - b.iter(|| { - let outer = Outer { - inner: vec!(), - }; - - let mut d = deserializer::OuterDeserializer::new(outer.clone()); - let value: Outer = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} - -#[bench] -fn bench_deserializer_1_0(b: &mut Bencher) { - b.iter(|| { - let map = HashMap::new(); - - let outer = Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: map, - }, - ) - }; - - let mut d = deserializer::OuterDeserializer::new(outer.clone()); - let value: Outer = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} - -#[bench] -fn bench_deserializer_1_5(b: &mut Bencher) { - b.iter(|| { - let mut map = HashMap::new(); - map.insert("1".to_string(), Some('a')); - map.insert("2".to_string(), None); - map.insert("3".to_string(), Some('b')); - map.insert("4".to_string(), None); - map.insert("5".to_string(), Some('c')); - - let outer = Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: map, - }, - ) - }; - - let mut d = deserializer::OuterDeserializer::new(outer.clone()); - let value: Outer = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, outer); - }) -} diff --git a/serde2/benches/bench_vec.rs b/serde2/benches/bench_vec.rs deleted file mode 100644 index 23eb9dc9..00000000 --- a/serde2/benches/bench_vec.rs +++ /dev/null @@ -1,615 +0,0 @@ -#![feature(core, plugin, test)] -#![plugin(serde2_macros)] - -extern crate serde2; -extern crate "rustc-serialize" as rustc_serialize; -extern crate test; - -use std::fmt::Debug; -use test::Bencher; - -use rustc_serialize::{Decoder, Decodable}; - -use serde2::de::{Deserializer, Deserialize}; - -////////////////////////////////////////////////////////////////////////////// - -#[derive(PartialEq, Debug)] -pub enum Error { - EndOfStreamError, - SyntaxError, -} - -impl serde2::de::Error for Error { - fn syntax_error() -> Error { Error::SyntaxError } - - fn end_of_stream_error() -> Error { Error::EndOfStreamError } - - fn missing_field_error(_: &'static str) -> Error { Error::SyntaxError } -} - -////////////////////////////////////////////////////////////////////////////// - -mod decoder { - use std::vec; - use rustc_serialize; - - use super::Error; - - pub struct UsizeDecoder { - len: usize, - iter: vec::IntoIter, - } - - impl UsizeDecoder { - #[inline] - pub fn new(values: Vec) -> UsizeDecoder { - UsizeDecoder { - len: values.len(), - iter: values.into_iter(), - } - } - } - - impl rustc_serialize::Decoder for UsizeDecoder { - type Error = Error; - - fn error(&mut self, _: &str) -> Error { Error::SyntaxError } - - // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } - #[inline] - fn read_usize(&mut self) -> Result { - match self.iter.next() { - Some(value) => Ok(value), - None => Err(Error::EndOfStreamError), - } - } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_str(&mut self) -> Result { Err(Error::SyntaxError) } - - // Compound types: - fn read_enum(&mut self, _name: &str, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - // Specialized types: - fn read_option(&mut self, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder, bool) -> Result, - { - Err(Error::SyntaxError) - } - - #[inline] - fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut UsizeDecoder, usize) -> Result, - { - let len = self.len; - f(self, len) - } - #[inline] - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - f(self) - } - - fn read_map(&mut self, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut UsizeDecoder) -> Result, - { - Err(Error::SyntaxError) - } - } - - - pub struct U8Decoder { - len: usize, - iter: vec::IntoIter, - } - - impl U8Decoder { - #[inline] - pub fn new(values: Vec) -> U8Decoder { - U8Decoder { - len: values.len(), - iter: values.into_iter(), - } - } - } - - impl rustc_serialize::Decoder for U8Decoder { - type Error = Error; - - fn error(&mut self, _: &str) -> Error { Error::SyntaxError } - - // Primitive types: - fn read_nil(&mut self) -> Result<(), Error> { Err(Error::SyntaxError) } - fn read_usize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_u16(&mut self) -> Result { Err(Error::SyntaxError) } - #[inline] - fn read_u8(&mut self) -> Result { - match self.iter.next() { - Some(value) => Ok(value), - None => Err(Error::EndOfStreamError), - } - } - #[inline] - fn read_isize(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i16(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_i8(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_bool(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f64(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_f32(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_char(&mut self) -> Result { Err(Error::SyntaxError) } - fn read_str(&mut self) -> Result { Err(Error::SyntaxError) } - - // Compound types: - fn read_enum(&mut self, _name: &str, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut U8Decoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_variant_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant(&mut self, _names: &[&str], _f: F) -> Result where - F: FnOnce(&mut U8Decoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_struct_field(&mut self, _f_name: &str, _f_idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple(&mut self, _len: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct(&mut self, _s_name: &str, _len: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_tuple_struct_arg(&mut self, _a_idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - // Specialized types: - fn read_option(&mut self, _f: F) -> Result where - F: FnOnce(&mut U8Decoder, bool) -> Result, - { - Err(Error::SyntaxError) - } - - #[inline] - fn read_seq(&mut self, f: F) -> Result where - F: FnOnce(&mut U8Decoder, usize) -> Result, - { - let len = self.len; - f(self, len) - } - #[inline] - fn read_seq_elt(&mut self, _idx: usize, f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - f(self) - } - - fn read_map(&mut self, _f: F) -> Result where - F: FnOnce(&mut U8Decoder, usize) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_key(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - - fn read_map_elt_val(&mut self, _idx: usize, _f: F) -> Result where - F: FnOnce(&mut U8Decoder) -> Result, - { - Err(Error::SyntaxError) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -mod deserializer { - //use std::num; - use std::vec; - - use super::Error; - - use serde2::de; - - #[derive(PartialEq, Debug)] - enum State { - StartState, - SepOrEndState, - EndState, - } - - pub struct Deserializer { - state: State, - iter: vec::IntoIter, - len: usize, - value: Option, - } - - impl Deserializer { - #[inline] - pub fn new(values: Vec) -> Deserializer { - let len = values.len(); - Deserializer { - state: State::StartState, - iter: values.into_iter(), - len: len, - value: None, - } - } - } - - impl de::Deserializer for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.state { - State::StartState => { - self.state = State::SepOrEndState; - visitor.visit_seq(self) - } - State::SepOrEndState => { - visitor.visit_usize(self.value.take().unwrap()) - } - State::EndState => { - Err(Error::EndOfStreamError) - } - } - } - } - - impl de::SeqVisitor for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize, - { - match self.iter.next() { - Some(value) => { - self.len -= 1; - self.value = Some(value); - Ok(Some(try!(de::Deserialize::deserialize(self)))) - } - None => { - self.state = State::EndState; - Ok(None) - } - } - } - - #[inline] - fn end(&mut self) -> Result<(), Error> { - match self.iter.next() { - Some(_) => Err(Error::SyntaxError), - None => { - self.state = State::EndState; - Ok(()) - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } - } - - impl de::Deserializer for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.state { - State::StartState => { - self.state = State::SepOrEndState; - visitor.visit_seq(self) - } - State::SepOrEndState => { - visitor.visit_u8(self.value.take().unwrap()) - } - State::EndState => { - Err(Error::EndOfStreamError) - } - } - } - } - - impl de::SeqVisitor for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize, - { - match self.iter.next() { - Some(value) => { - self.len -= 1; - self.value = Some(value); - Ok(Some(try!(de::Deserialize::deserialize(self)))) - } - None => { - self.state = State::EndState; - Ok(None) - } - } - } - - #[inline] - fn end(&mut self) -> Result<(), Error> { - match self.iter.next() { - Some(_) => Err(Error::SyntaxError), - None => { - self.state = State::EndState; - Ok(()) - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -fn run_decoder< - D: Decoder, - T: Clone + PartialEq + Debug + Decodable ->(mut d: D, value: T) { - let v = Decodable::decode(&mut d); - - assert_eq!(Ok(value), v); -} - -fn run_deserializer< - D: Deserializer, - E: Debug, - T: Clone + PartialEq + Debug + Deserialize ->(mut d: D, value: T) { - let v: T = Deserialize::deserialize(&mut d).unwrap(); - - assert_eq!(value, v); -} - -#[bench] -fn bench_decoder_usize_000(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(); - run_decoder(decoder::UsizeDecoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_decoder_usize_003(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_decoder(decoder::UsizeDecoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_decoder_usize_100(b: &mut Bencher) { - b.iter(|| { - let v: Vec = range(0, 100).collect(); - run_decoder(decoder::UsizeDecoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_decoder_u8_000(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(); - run_decoder(decoder::U8Decoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_decoder_u8_003(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_decoder(decoder::U8Decoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_decoder_u8_100(b: &mut Bencher) { - b.iter(|| { - let v: Vec = range(0u8, 100).collect(); - run_decoder(decoder::U8Decoder::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_usize_000(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_usize_003(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_usize_100(b: &mut Bencher) { - b.iter(|| { - let v: Vec = range(0, 100).collect(); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_u8_000(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_u8_003(b: &mut Bencher) { - b.iter(|| { - let v: Vec = vec!(1, 2, 3); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} - -#[bench] -fn bench_deserializer_u8_100(b: &mut Bencher) { - b.iter(|| { - let v: Vec = range(0u8, 100).collect(); - run_deserializer(deserializer::Deserializer::new(v.clone()), v) - }) -} diff --git a/serde2/serde2_macros/.gitignore b/serde2/serde2_macros/.gitignore deleted file mode 100644 index ea8c4bf7..00000000 --- a/serde2/serde2_macros/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/serde2/serde2_macros/Cargo.toml b/serde2/serde2_macros/Cargo.toml deleted file mode 100644 index 90607a22..00000000 --- a/serde2/serde2_macros/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "serde2_macros" -version = "0.1.0" -authors = ["Erick Tryzelaar "] - -[lib] -name = "serde2_macros" -plugin = true - -[dependencies] -quasi = "0.1.0" -quasi_macros = "0.1.0" -aster = "0.1.2" diff --git a/serde2/serde2_macros/src/lib.rs b/serde2/serde2_macros/src/lib.rs deleted file mode 100644 index c17e3a59..00000000 --- a/serde2/serde2_macros/src/lib.rs +++ /dev/null @@ -1,1443 +0,0 @@ -#![feature(custom_derive, plugin, plugin_registrar, rustc_private, unboxed_closures)] -#![plugin(quasi_macros)] - -extern crate aster; -extern crate quasi; -extern crate rustc; -extern crate syntax; - -use syntax::ast::{ - Ident, - MetaItem, - MetaItem_, - Item, - Expr, - MutMutable, - StructDef, - EnumDef, -}; -use syntax::ast; -use syntax::ast_util; -use syntax::codemap::{Span, respan}; -use syntax::ext::base::{ExtCtxt, Decorator, ItemDecorator}; -use syntax::ext::build::AstBuilder; -use syntax::ext::deriving::generic::{ - EnumMatching, - FieldInfo, - MethodDef, - Named, - StaticFields, - StaticStruct, - StaticEnum, - Struct, - Substructure, - TraitDef, - Unnamed, - combine_substructure, -}; -use syntax::ext::deriving::generic::ty::{ - Borrowed, - LifetimeBounds, - Ty, - Path, - borrowed_explicit_self, -}; -use syntax::parse::token; -use syntax::ptr::P; - -use rustc::plugin::Registry; - -#[plugin_registrar] -#[doc(hidden)] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - token::intern("derive_serialize"), - Decorator(Box::new(expand_derive_serialize))); - - reg.register_syntax_extension( - token::intern("derive_deserialize"), - Decorator(Box::new(expand_derive_deserialize))); -} - -fn expand_derive_serialize( - cx: &mut ExtCtxt, - sp: Span, - mitem: &MetaItem, - item: &Item, - push: &mut FnMut(P) -) { - let inline = cx.meta_word(sp, token::InternedString::new("inline")); - let attrs = vec!(cx.attribute(sp, inline)); - - let trait_def = TraitDef { - span: sp, - attributes: vec![], - path: Path::new(vec!["serde2", "ser", "Serialize"]), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - associated_types: vec![], - methods: vec![ - MethodDef { - name: "visit", - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec![ - ("__V", vec![Path::new(vec!["serde2", "ser", "Visitor"])]), - ] - }, - explicit_self: borrowed_explicit_self(), - args: vec![ - Ty::Ptr( - Box::new(Ty::Literal(Path::new_local("__V"))), - Borrowed(None, MutMutable), - ), - ], - ret_ty: Ty::Literal( - Path::new_( - vec!("std", "result", "Result"), - None, - vec![ - Box::new(Ty::Literal(Path::new_(vec!["__V", "Value"], - None, - vec![], - false))), - Box::new(Ty::Literal(Path::new_(vec!["__V", "Error"], - None, - vec![], - false))), - ], - true - ) - ), - attributes: attrs, - combine_substructure: combine_substructure(Box::new(|a, b, c| { - serialize_substructure(a, b, c, item) - })), - } - ] - }; - - trait_def.expand(cx, mitem, item, |item| push(item)) -} - -fn serialize_substructure( - cx: &ExtCtxt, - span: Span, - substr: &Substructure, - item: &Item, -) -> P { - let builder = aster::AstBuilder::new().span(span); - - let visitor = substr.nonself_args[0].clone(); - - match (&item.node, &*substr.fields) { - (&ast::ItemStruct(ref struct_def, ref generics), &Struct(ref fields)) => { - let mut named_fields = vec![]; - let mut unnamed_fields = vec![]; - - for field in fields { - match field.name { - Some(name) => { named_fields.push((name, field.span)); } - None => { unnamed_fields.push(field.span); } - } - } - - match (named_fields.is_empty(), unnamed_fields.is_empty()) { - (true, true) => { - serialize_unit_struct( - cx, - &builder, - visitor, - substr.type_ident, - ) - } - (true, false) => { - serialize_tuple_struct( - cx, - &builder, - visitor, - substr.type_ident, - &unnamed_fields, - generics, - ) - } - (false, true) => { - serialize_struct( - cx, - &builder, - visitor, - substr.type_ident, - &named_fields, - struct_def, - generics, - ) - } - (false, false) => { - panic!("struct has named and unnamed fields") - } - } - } - - (&ast::ItemEnum(_, ref generics), &EnumMatching(_idx, variant, ref fields)) => { - serialize_enum( - cx, - span, - &builder, - visitor, - substr.type_ident, - variant, - &fields, - generics, - ) - } - - _ => cx.bug("expected Struct or EnumMatching in derive_serialize") - } -} - -fn serialize_unit_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - visitor: P, - type_ident: Ident -) -> P { - let type_name = builder.expr().str(type_ident); - - quote_expr!(cx, $visitor.visit_named_unit($type_name)) -} - -fn serialize_tuple_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - visitor: P, - type_ident: Ident, - fields: &[Span], - generics: &ast::Generics -) -> P { - let type_name = builder.expr().str(type_ident); - let len = fields.len(); - - let arms: Vec = (0 .. fields.len()) - .map(|i| { - let first = builder.expr().bool(i == 0); - let expr = builder.expr() - .tup_field(i) - .field("value").self_(); - - quote_arm!(cx, - $i => { - self.state += 1; - let v = try!(visitor.visit_seq_elt($first, &$expr)); - Ok(Some(v)) - } - ) - }) - .collect(); - - let type_generics = builder.from_generics(generics.clone()) - .strip_bounds() - .build(); - - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "ser", "Serialize"]).build() - ) - .lifetime_name("'__a") - .build(); - - let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) - .strip_bounds() - .build(); - - quote_expr!(cx, { - struct Visitor $visitor_impl_generics { - state: usize, - value: &'__a $type_ident $type_generics, - } - - impl $visitor_impl_generics ::serde2::ser::SeqVisitor for Visitor $visitor_generics { - #[inline] - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: ::serde2::ser::Visitor, - { - match self.state { - $arms - _ => Ok(None), - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let size = $len - (self.state as usize); - (size, Some(size)) - } - } - - $visitor.visit_named_seq($type_name, Visitor { - value: self, - state: 0, - }) - }) -} - -fn serialize_struct( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - visitor: P, - type_ident: Ident, - fields: &[(Ident, Span)], - struct_def: &StructDef, - generics: &ast::Generics -) -> P { - let type_name = builder.expr().str(type_ident); - let len = fields.len(); - - let aliases : Vec> = struct_def.fields.iter() - .map(field_alias) - .collect(); - - let arms: Vec = fields.iter() - .zip(aliases.iter()) - .enumerate() - .map(|(i, (&(name, _), alias_lit))| { - let first = builder.expr().bool(i == 0); - - let expr = match *alias_lit { - Some(lit) => builder.expr().build_lit(P(lit.clone())), - None => builder.expr().str(name), - }; - - quote_arm!(cx, - $i => { - self.state += 1; - let v = try!(visitor.visit_map_elt($first, $expr, &self.value.$name)); - Ok(Some(v)) - } - ) - }) - .collect(); - - let type_generics = builder.from_generics(generics.clone()) - .strip_bounds() - .build(); - - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "ser", "Serialize"]).build() - ) - .lifetime_name("'__a") - .build(); - - let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) - .strip_bounds() - .build(); - - quote_expr!(cx, { - struct Visitor $visitor_impl_generics { - state: usize, - value: &'__a $type_ident $type_generics, - } - - impl $visitor_impl_generics ::serde2::ser::MapVisitor for Visitor $visitor_generics { - #[inline] - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: ::serde2::ser::Visitor, - { - match self.state { - $arms - _ => Ok(None), - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let size = $len - (self.state as usize); - (size, Some(size)) - } - } - - $visitor.visit_named_map($type_name, Visitor { - value: self, - state: 0, - }) - }) -} - -fn serialize_enum( - cx: &ExtCtxt, - span: Span, - builder: &aster::AstBuilder, - visitor: P, - type_ident: Ident, - variant: &ast::Variant, - fields: &[FieldInfo], - generics: &ast::Generics, -) -> P { - let type_name = builder.expr().str(type_ident); - let variant_name = builder.expr().str(variant.node.name); - - if fields.is_empty() { - quote_expr!(cx, - ::serde2::ser::Visitor::visit_enum_unit( - $visitor, - $type_name, - $variant_name) - ) - } else { - serialize_variant( - cx, - span, - builder, - visitor, - type_name, - variant_name, - generics, - variant, - fields) - } -} - -fn serialize_variant( - cx: &ExtCtxt, - span: Span, - builder: &aster::AstBuilder, - visitor: P, - type_name: P, - variant_name: P, - generics: &ast::Generics, - variant: &ast::Variant, - fields: &[FieldInfo], -) -> P { - let generics = builder.from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "ser", "Serialize"]).build() - ) - .lifetime_name("'__a") - .build(); - - let ( - trait_name, - visitor_method_name, - tys, - ): (Ident, Ident, Vec>) = match variant.node.kind { - ast::TupleVariantKind(ref args) => { - ( - cx.ident_of("SeqVisitor"), - cx.ident_of("visit_enum_seq"), - args.iter() - .map(|arg| arg.ty.clone()) - .collect() - ) - } - - ast::StructVariantKind(ref struct_def) => { - ( - cx.ident_of("MapVisitor"), - cx.ident_of("visit_enum_map"), - struct_def.fields.iter() - .map(|field| field.node.ty.clone()) - .collect() - ) - } - }; - - let value_ty = builder.ty() - .tuple() - .with_tys(tys.into_iter().map(|ty| { - builder.ty() - .ref_() - .lifetime("'__a") - .build_ty(ty) - })) - .build(); - - let visitor_ident = builder.id("__Visitor"); - - let visitor_struct = builder.item().struct_(visitor_ident) - .generics().with(generics.clone()).build() - .field("state").usize() - .field("value").build(value_ty) - .build(); - - let visitor_expr = builder.expr().struct_path(visitor_ident) - .field("state").usize(0) - .field("value").tuple() - .with_exprs( - fields.iter().map(|field| { - builder.expr() - .addr_of() - .build(field.self_.clone()) - }) - ) - .build() - .build(); - - let mut first = true; - - let visitor_arms: Vec = fields.iter() - .enumerate() - .map(|(state, field)| { - let field_expr = builder.expr() - .tup_field(state) - .field("value").self_(); - - let visit_expr = match field.name { - Some(real_name) => { - let real_name = builder.expr().str(real_name); - - quote_expr!(cx, - ::serde2::ser::Visitor::visit_map_elt( - visitor, - $first, - $real_name, - $field_expr, - ) - ) - } - None => { - quote_expr!(cx, - ::serde2::ser::Visitor::visit_seq_elt( - visitor, - $first, - $field_expr, - ) - ) - } - }; - - first = false; - - quote_arm!(cx, - $state => { - self.state += 1; - Ok(Some(try!($visit_expr))) - } - ) - }) - .collect(); - - let trait_path = builder.path() - .global() - .ids(&["serde2", "ser"]).id(trait_name) - .build(); - - let trait_ref = cx.trait_ref(trait_path); - let opt_trait_ref = Some(trait_ref); - - let self_ty = builder.ty() - .path() - .segment("__Visitor") - .with_generics(generics.clone()) - .build() - .build(); - - let len = fields.len(); - let impl_ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&self_ty)); - - let methods = vec![ - ast::MethodImplItem( - quote_method!(cx, - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: ::serde2::ser::Visitor, - { - match self.state { - $visitor_arms - _ => Ok(None), - } - } - ) - ), - - ast::MethodImplItem( - quote_method!(cx, - fn size_hint(&self) -> (usize, Option) { - ($len - self.state as usize, Some($len - self.state as usize)) - } - ) - ), - ]; - - let visitor_impl = cx.item( - span, - impl_ident, - vec![], - ast::ItemImpl( - ast::Unsafety::Normal, - ast::ImplPolarity::Positive, - generics, - opt_trait_ref, - self_ty, - methods, - ), - ); - - quote_expr!(cx, { - $visitor_struct - $visitor_impl - - ::serde2::ser::Visitor::$visitor_method_name( - $visitor, - $type_name, - $variant_name, - $visitor_expr, - ) - }) -} - -pub fn expand_derive_deserialize( - cx: &mut ExtCtxt, - sp: Span, - mitem: &MetaItem, - item: &Item, - push: &mut FnMut(P) -) { - let inline = cx.meta_word(sp, token::InternedString::new("inline")); - let attrs = vec!(cx.attribute(sp, inline)); - - let trait_def = TraitDef { - span: sp, - attributes: Vec::new(), - path: Path::new(vec!["serde2", "de", "Deserialize"]), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - associated_types: vec![], - methods: vec!( - MethodDef { - name: "deserialize", - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec![ - ("__D", vec![Path::new(vec!["serde2", "de", "Deserializer"])]), - ], - }, - explicit_self: None, - args: vec![ - Ty::Ptr( - Box::new(Ty::Literal(Path::new_local("__D"))), - Borrowed(None, MutMutable) - ), - ], - ret_ty: Ty::Literal( - Path::new_( - vec!["std", "result", "Result"], - None, - vec![ - Box::new(Ty::Self_), - Box::new(Ty::Literal(Path::new_(vec!["__D", "Error"], - None, - vec![], - false))), - ], - true - ) - ), - attributes: attrs, - combine_substructure: combine_substructure(Box::new(|a, b, c| { - deserialize_substructure(a, b, c, item) - })), - }) - }; - - trait_def.expand(cx, mitem, item, |item| push(item)) -} - -fn deserialize_substructure( - cx: &ExtCtxt, - span: Span, - substr: &Substructure, - item: &Item, -) -> P { - let builder = aster::AstBuilder::new().span(span); - - let state = substr.nonself_args[0].clone(); - - match (&item.node, &*substr.fields) { - (&ast::ItemStruct(_, ref generics), &StaticStruct(ref struct_def, ref fields)) => { - deserialize_struct( - cx, - span, - &builder, - substr.type_ident, - substr.type_ident, - cx.path(span, vec![substr.type_ident]), - fields, - state, - struct_def, - generics, - ) - } - (&ast::ItemEnum(_, ref generics), &StaticEnum(ref enum_def, ref fields)) => { - deserialize_enum( - cx, - &builder, - substr.type_ident, - &fields, - state, - enum_def, - generics, - ) - } - _ => cx.bug("expected StaticEnum or StaticStruct in derive(Deserialize)") - } -} - -fn deserialize_struct( - cx: &ExtCtxt, - span: Span, - builder: &aster::AstBuilder, - type_ident: Ident, - struct_ident: Ident, - struct_path: ast::Path, - fields: &StaticFields, - state: P, - struct_def: &StructDef, - generics: &ast::Generics, -) -> P { - match *fields { - Unnamed(ref fields) => { - if fields.is_empty() { - deserialize_struct_empty_fields( - cx, - builder, - type_ident, - struct_ident, - struct_path, - state) - } else { - deserialize_struct_unnamed_fields( - cx, - builder, - type_ident, - struct_ident, - struct_path, - &fields, - state, - generics, - ) - } - } - Named(ref fields) => { - deserialize_struct_named_fields( - cx, - span, - builder, - type_ident, - struct_ident, - struct_path, - &fields, - state, - struct_def, - generics) - } - } -} - -fn deserialize_struct_empty_fields( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - type_ident: Ident, - struct_ident: Ident, - struct_path: ast::Path, - state: P, -) -> P { - let struct_name = builder.expr().str(struct_ident); - let result = builder.expr().build_path(struct_path); - - quote_expr!(cx, { - struct __Visitor; - - impl ::serde2::de::Visitor for __Visitor { - type Value = $type_ident; - - #[inline] - fn visit_unit(&mut self) -> Result<$type_ident, E> - where E: ::serde2::de::Error, - { - Ok($result) - } - - #[inline] - fn visit_named_unit< - E: ::serde2::de::Error, - >(&mut self, name: &str) -> Result<$type_ident, E> { - if name == $struct_name { - self.visit_unit() - } else { - Err(::serde2::de::Error::syntax_error()) - } - } - - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result<$type_ident, V::Error> - where V: ::serde2::de::SeqVisitor, - { - try!(visitor.end()); - self.visit_unit() - } - } - - $state.visit(__Visitor) - }) -} - -fn deserialize_struct_unnamed_fields( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - type_ident: Ident, - struct_ident: Ident, - struct_path: ast::Path, - fields: &[Span], - state: P, - generics: &ast::Generics, -) -> P { - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "de", "Deserialize"]).build() - ) - .build(); - - let field_names: Vec = (0 .. fields.len()) - .map(|i| builder.id(&format!("__field{}", i))) - .collect(); - - let visit_seq_expr = declare_visit_seq( - cx, - builder, - struct_path, - &field_names, - ); - - // Build `__Visitor(PhantomData, PhantomData, ...)` - let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { - ( - builder.item().tuple_struct("__Visitor") - .build(), - builder.expr().id("__Visitor"), - ) - } else { - ( - builder.item().tuple_struct("__Visitor") - .generics().with(generics.clone()).build() - .with_tys( - generics.ty_params.iter().map(|ty_param| { - builder.ty().phantom_data().id(ty_param.ident) - }) - ) - .build(), - builder.expr().call().id("__Visitor") - .with_args( - generics.ty_params.iter().map(|_| { - builder.expr().phantom_data() - }) - ) - .build(), - ) - }; - - let struct_name = builder.expr().str(struct_ident); - - let visitor_ty = builder.ty().path() - .segment("__Visitor").with_generics(generics.clone()).build() - .build(); - - let value_ty = builder.ty().path() - .segment(type_ident).with_generics(generics.clone()).build() - .build(); - - quote_expr!(cx, { - $visitor_struct; - - impl $visitor_impl_generics ::serde2::de::Visitor for $visitor_ty { - type Value = $value_ty; - - fn visit_seq<__V>(&mut self, mut visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::SeqVisitor, - { - $visit_seq_expr - } - - fn visit_named_seq<__V>(&mut self, - name: &str, - visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::SeqVisitor, - { - if name == $struct_name { - self.visit_seq(visitor) - } else { - Err(::serde2::de::Error::syntax_error()) - } - } - } - - $state.visit($visitor_expr) - }) -} - -fn declare_visit_seq( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - struct_path: ast::Path, - field_names: &[Ident], -) -> P { - let let_values: Vec> = field_names.iter() - .map(|name| { - quote_stmt!(cx, - let $name = match try!(visitor.visit()) { - Some(value) => value, - None => { - return Err(::serde2::de::Error::end_of_stream_error()); - } - }; - ) - }) - .collect(); - - let result = builder.expr().call() - .build_path(struct_path) - .with_args(field_names.iter().map(|name| builder.expr().id(*name))) - .build(); - - quote_expr!(cx, { - $let_values - - try!(visitor.end()); - - Ok($result) - }) -} - -fn deserialize_struct_named_fields( - cx: &ExtCtxt, - span: Span, - builder: &aster::AstBuilder, - type_ident: Ident, - struct_ident: Ident, - struct_path: ast::Path, - fields: &[(Ident, Span)], - state: P, - struct_def: &StructDef, - generics: &ast::Generics, -) -> P { - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "de", "Deserialize"]).build() - ) - .build(); - - // Create the field names for the fields. - let field_names: Vec = (0 .. fields.len()) - .map(|i| token::str_to_ident(&format!("__field{}", i))) - .collect(); - - // Build `__Visitor(PhantomData, PhantomData, ...)` - let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { - ( - builder.item().tuple_struct("__Visitor") - .build(), - builder.expr().id("__Visitor"), - ) - } else { - ( - builder.item().tuple_struct("__Visitor") - .generics().with(generics.clone()).build() - .with_tys( - generics.ty_params.iter().map(|ty_param| { - builder.ty().phantom_data().id(ty_param.ident) - }) - ) - .build(), - builder.expr().call().id("__Visitor") - .with_args( - generics.ty_params.iter().map(|_| { - builder.expr().phantom_data() - }) - ) - .build(), - ) - }; - - let struct_name = builder.expr().str(struct_ident); - - let visitor_ty = builder.ty().path() - .segment("__Visitor").with_generics(generics.clone()).build() - .build(); - - let value_ty = builder.ty().path() - .segment(type_ident).with_generics(generics.clone()).build() - .build(); - - let field_deserializer = declare_map_field_deserializer( - cx, - span, - builder, - &field_names, - fields, - struct_def, - ); - - let visit_map_expr = declare_visit_map( - cx, - builder, - struct_path, - &field_names, - fields, - struct_def - ); - - quote_expr!(cx, { - $field_deserializer - - $visitor_struct; - - impl $visitor_impl_generics ::serde2::de::Visitor for $visitor_ty { - type Value = $value_ty; - - #[inline] - fn visit_map<__V>(&mut self, mut visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::MapVisitor, - { - $visit_map_expr - } - - #[inline] - fn visit_named_map<__V>(&mut self, - name: &str, - visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::MapVisitor, - { - if name == $struct_name { - self.visit_map(visitor) - } else { - Err(::serde2::de::Error::syntax_error()) - } - } - } - - $state.visit($visitor_expr) - }) -} - -fn field_alias(field: &ast::StructField) -> Option<&ast::Lit> { - field.node.attrs.iter() - .find(|sa| - if let MetaItem_::MetaList(ref n, _) = sa.node.value.node { - n == &"serde" - } else { - false - }) - .and_then(|sa| - if let MetaItem_::MetaList(_, ref vals) = sa.node.value.node { - vals.iter() - .fold(None, - |v, mi| - if let MetaItem_::MetaNameValue(ref n, ref lit) = mi.node { - if n == &"alias" { - Some(lit) - } else { - v - } - } else { - v - }) - } else { - None - }) -} - -fn declare_map_field_deserializer( - cx: &ExtCtxt, - span: Span, - _builder: &aster::AstBuilder, - field_names: &[ast::Ident], - fields: &[(Ident, Span)], - struct_def: &StructDef, -) -> Vec> { - // Create the field names for the fields. - let field_variants: Vec> = field_names.iter() - .map(|field| { - P(respan( - span, - ast::Variant_ { - name: *field, - attrs: Vec::new(), - kind: ast::TupleVariantKind(Vec::new()), - id: ast::DUMMY_NODE_ID, - disr_expr: None, - vis: ast::Inherited, - })) - }) - .collect(); - - let field_enum = cx.item_enum( - span, - token::str_to_ident("__Field"), - ast::EnumDef { variants: field_variants }); - - // Get aliases - let aliases : Vec> = struct_def.fields.iter() - .map(field_alias) - .collect(); - - // Match arms to extract a field from a string - let field_arms: Vec = fields.iter() - .zip(field_names.iter()) - .zip(aliases.iter()) - .map(|((&(name, span), field), alias_lit)| { - let s = match alias_lit { - &None => cx.expr_str(span, token::get_ident(name)) , - &Some(lit) =>{ - let lit = (*lit).clone(); - cx.expr_lit(lit.span, lit.node) - }, - }; - quote_arm!(cx, $s => Ok(__Field::$field),)}) - .collect(); - - vec![ - quote_item!(cx, - #[allow(non_camel_case_types)] - $field_enum - ).unwrap(), - - quote_item!(cx, - struct __FieldVisitor; - ).unwrap(), - - quote_item!(cx, - impl ::serde2::de::Visitor for __FieldVisitor { - type Value = __Field; - - fn visit_str(&mut self, value: &str) -> Result<__Field, E> - where E: ::serde2::de::Error, - { - match value { - $field_arms - _ => Err(::serde2::de::Error::syntax_error()), - } - } - } - ).unwrap(), - - quote_item!(cx, - impl ::serde2::de::Deserialize for __Field { - #[inline] - fn deserialize(state: &mut S) -> Result<__Field, S::Error> - where S: ::serde2::de::Deserializer, - { - state.visit(__FieldVisitor) - } - } - ).unwrap(), - ] -} - - -fn default_value(field: &ast::StructField) -> bool { - field.node.attrs.iter() - .any(|sa| - if let MetaItem_::MetaList(ref n, ref vals) = sa.node.value.node { - if n == &"serde" { - vals.iter() - .map(|mi| - if let MetaItem_::MetaWord(ref n) = mi.node { - n == &"default" - } else { - false - }) - .any(|x| x) - } else { - false - } - } - else { - false - }) -} - -fn declare_visit_map( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - struct_path: ast::Path, - field_names: &[Ident], - fields: &[(Ident, Span)], - struct_def: &StructDef, -) -> P { - - // Declare each field. - let let_values: Vec> = field_names.iter() - .zip(struct_def.fields.iter()) - .map(|(field, sf)| { - if default_value(sf) { - quote_stmt!( - cx, - let mut $field = Some(::std::default::Default::default());) - } else { - quote_stmt!(cx, let mut $field = None;) - } - }) - .collect(); - - // Match arms to extract a value for a field. - let value_arms: Vec = field_names.iter() - .map(|field| { - quote_arm!(cx, __Field::$field => { - $field = Some(try!(visitor.visit_value())); - }) - }) - .collect(); - - let extract_values: Vec> = fields.iter() - .zip(field_names.iter()) - .map(|(&(name, span), field)| { - let name_str = cx.expr_str(span, token::get_ident(name)); - quote_stmt!(cx, - let $field = match $field { - Some($field) => $field, - None => { - return Err(::serde2::de::Error::missing_field_error($name_str)); - } - }; - ) - }) - .collect(); - - let result = builder.expr().struct_path(struct_path) - .with_id_exprs( - fields.iter() - .zip(field_names.iter()) - .map(|(&(name, _), field)| { - (name, builder.expr().id(field)) - }) - ) - .build(); - - quote_expr!(cx, { - $let_values - - while let Some(key) = try!(visitor.visit_key()) { - match key { - $value_arms - } - } - - $extract_values - Ok($result) - }) -} - -fn deserialize_enum( - cx: &ExtCtxt, - builder: &aster::AstBuilder, - type_ident: Ident, - fields: &[(Ident, Span, StaticFields)], - state: P, - enum_def: &EnumDef, - generics: &ast::Generics, -) -> P { - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_ty_param_bound( - builder.path().global().ids(&["serde2", "de", "Deserialize"]).build() - ) - .build(); - - // Build `__Visitor(PhantomData, PhantomData, ...)` - let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { - ( - builder.item().tuple_struct("__Visitor") - .build(), - builder.expr().id("__Visitor"), - ) - } else { - ( - builder.item().tuple_struct("__Visitor") - .generics().with(generics.clone()).build() - .with_tys( - generics.ty_params.iter().map(|ty_param| { - builder.ty().phantom_data().id(ty_param.ident) - }) - ) - .build(), - builder.expr().call().id("__Visitor") - .with_args( - generics.ty_params.iter().map(|_| { - builder.expr().phantom_data() - }) - ) - .build(), - ) - }; - - let visitor_ty = builder.ty().path() - .segment("__Visitor").with_generics(generics.clone()).build() - .build(); - - let value_ty = builder.ty().path() - .segment(type_ident).with_generics(generics.clone()).build() - .build(); - - let type_name = builder.expr().str(type_ident); - - // Match arms to extract a variant from a string - let variant_arms: Vec = fields.iter() - .zip(enum_def.variants.iter()) - .map(|(&(name, span, ref fields), variant_ptr)| { - let value = deserialize_enum_variant( - cx, - span, - builder, - type_ident, - name, - fields, - cx.expr_ident(span, cx.ident_of("visitor")), - variant_ptr, - &visitor_impl_generics, - &visitor_ty, - &visitor_expr, - &value_ty, - ); - - let s = builder.expr().str(name); - quote_arm!(cx, $s => $value,) - }) - .collect(); - - quote_expr!(cx, { - $visitor_struct; - - impl $visitor_impl_generics ::serde2::de::Visitor for $visitor_ty { - type Value = $value_ty; - - fn visit_enum<__V>(&mut self, - name: &str, - variant: &str, - visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::EnumVisitor, - { - if name == $type_name { - self.visit_variant(variant, visitor) - } else { - Err(::serde2::de::Error::syntax_error()) - } - } - - fn visit_variant<__V>(&mut self, - name: &str, - mut visitor: __V) -> Result<$value_ty, __V::Error> - where __V: ::serde2::de::EnumVisitor - { - match name { - $variant_arms - _ => Err(::serde2::de::Error::syntax_error()), - } - } - } - - $state.visit_enum($visitor_expr) - }) -} - -fn deserialize_enum_variant( - cx: &ExtCtxt, - span: Span, - builder: &aster::AstBuilder, - type_ident: Ident, - variant_ident: Ident, - fields: &StaticFields, - state: P, - variant_ptr: &P, - visitor_impl_generics: &ast::Generics, - visitor_ty: &P, - visitor_expr: &P, - value_ty: &P, -) -> P { - let variant_path = cx.path(span, vec![type_ident, variant_ident]); - - match *fields { - Unnamed(ref fields) => { - if fields.is_empty() { - let result = cx.expr_path(variant_path); - - quote_expr!(cx, { - try!($state.visit_unit()); - Ok($result) - }) - } else { - // Create the field names for the fields. - let field_names: Vec = (0 .. fields.len()) - .map(|i| token::str_to_ident(&format!("__field{}", i))) - .collect(); - - let visit_seq_expr = declare_visit_seq( - cx, - builder, - variant_path, - &field_names, - ); - - quote_expr!(cx, { - impl $visitor_impl_generics ::serde2::de::EnumSeqVisitor for $visitor_ty { - type Value = $value_ty; - - fn visit< - V: ::serde2::de::SeqVisitor, - >(&mut self, mut visitor: V) -> Result<$value_ty, V::Error> { - $visit_seq_expr - } - } - - $state.visit_seq($visitor_expr) - }) - } - } - Named(ref fields) => { - // Create the field names for the fields. - let field_names: Vec = (0 .. fields.len()) - .map(|i| token::str_to_ident(&format!("__field{}", i))) - .collect(); - - let field_deserializer = declare_map_field_deserializer( - cx, - span, - builder, - &field_names, - fields, - match variant_ptr.node.kind { - ast::VariantKind::StructVariantKind(ref sd) => &*sd, - _ => panic!("Mismatched enum types") - }, - ); - - let visit_map_expr = declare_visit_map( - cx, - builder, - variant_path, - &field_names, - fields, - match variant_ptr.node.kind { - ast::VariantKind::StructVariantKind(ref sd) => &*sd, - _ => panic!("Mismatched enum types") - }, - ); - - quote_expr!(cx, { - $field_deserializer - - impl $visitor_impl_generics ::serde2::de::EnumMapVisitor for $visitor_ty { - type Value = $value_ty; - - fn visit< - V: ::serde2::de::MapVisitor, - >(&mut self, mut visitor: V) -> Result<$value_ty, V::Error> { - $visit_map_expr - } - } - - $state.visit_map($visitor_expr) - }) - } - } -} diff --git a/serde2/src/de.rs b/serde2/src/de.rs deleted file mode 100644 index 2bf7328d..00000000 --- a/serde2/src/de.rs +++ /dev/null @@ -1,819 +0,0 @@ -use std::collections::{HashMap, BTreeMap}; -use std::hash::Hash; -use std::marker::PhantomData; -use std::num::FromPrimitive; -use std::path; -use std::str; - -/////////////////////////////////////////////////////////////////////////////// - -pub trait Error { - fn syntax_error() -> Self; - - fn end_of_stream_error() -> Self; - - fn missing_field_error(&'static str) -> Self; -} - -pub trait Deserialize { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer; -} - -pub trait Deserializer { - type Error: Error; - - fn visit(&mut self, visitor: V) -> Result - where V: Visitor; - - /// The `visit_option` method allows a `Deserialize` type to inform the - /// `Deserializer` that it's expecting an optional value. This allows - /// deserializers that encode an optional value as a nullable value to - /// convert the null value into a `None`, and a regular value as - /// `Some(value)`. - #[inline] - fn visit_option(&mut self, visitor: V) -> Result - where V: Visitor, - { - self.visit(visitor) - } - - /// The `visit_enum` method allows a `Deserialize` type to inform the - /// `Deserializer` that it's expecting an enum value. This allows - /// deserializers that provide a custom enumeration serialization to - /// properly deserialize the type. - #[inline] - fn visit_enum(&mut self, visitor: V) -> Result - where V: Visitor, - { - self.visit(visitor) - } -} - -pub trait Visitor { - type Value; - - fn visit_bool(&mut self, _v: bool) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - fn visit_isize(&mut self, v: isize) -> Result - where E: Error, - { - self.visit_i64(v as i64) - } - - fn visit_i8(&mut self, v: i8) -> Result - where E: Error, - { - self.visit_i64(v as i64) - } - - fn visit_i16(&mut self, v: i16) -> Result - where E: Error, - { - self.visit_i64(v as i64) - } - - fn visit_i32(&mut self, v: i32) -> Result - where E: Error, - { - self.visit_i64(v as i64) - } - - fn visit_i64(&mut self, _v: i64) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - fn visit_usize(&mut self, v: usize) -> Result - where E: Error, - { - self.visit_u64(v as u64) - } - - fn visit_u8(&mut self, v: u8) -> Result - where E: Error, - { - self.visit_u64(v as u64) - } - - fn visit_u16(&mut self, v: u16) -> Result - where E: Error, - { - self.visit_u64(v as u64) - } - - fn visit_u32(&mut self, v: u32) -> Result - where E: Error, - { - self.visit_u64(v as u64) - } - - fn visit_u64(&mut self, _v: u64) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - fn visit_f32(&mut self, v: f32) -> Result - where E: Error, - { - self.visit_f64(v as f64) - } - - fn visit_f64(&mut self, _v: f64) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_char(&mut self, v: char) -> Result - where E: 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()) - } - - fn visit_str(&mut self, _v: &str) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_string(&mut self, v: String) -> Result - where E: Error, - { - self.visit_str(&v) - } - - fn visit_unit(&mut self) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_named_unit(&mut self, _name: &str) -> Result - where E: Error, - { - self.visit_unit() - } - - fn visit_none(&mut self) -> Result - where E: Error, - { - Err(Error::syntax_error()) - } - - fn visit_some(&mut self, _deserializer: &mut D) -> Result - where D: Deserializer, - { - Err(Error::syntax_error()) - } - - fn visit_seq(&mut self, _visitor: V) -> Result - where V: SeqVisitor, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_named_seq(&mut self, _name: &str, visitor: V) -> Result - where V: SeqVisitor, - { - self.visit_seq(visitor) - } - - fn visit_map(&mut self, _visitor: V) -> Result - where V: MapVisitor, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_named_map(&mut self, _name: &str, visitor: V) -> Result - where V: MapVisitor, - { - self.visit_map(visitor) - } - - #[inline] - fn visit_enum(&mut self, - _name: &str, - _variant: &str, - _visitor: V) -> Result - where V: EnumVisitor, - { - Err(Error::syntax_error()) - } - - #[inline] - fn visit_variant(&mut self, _name: &str, _visitor: V) -> Result - where V: EnumVisitor, - { - Err(Error::syntax_error()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait SeqVisitor { - type Error: Error; - - fn visit(&mut self) -> Result, Self::Error> - where T: Deserialize; - - fn end(&mut self) -> Result<(), Self::Error>; - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) - } -} - -impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor { - type Error = V::Error; - - #[inline] - fn visit(&mut self) -> Result, V::Error> - where T: Deserialize - { - (**self).visit() - } - - #[inline] - fn end(&mut self) -> Result<(), V::Error> { - (**self).end() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (**self).size_hint() - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait MapVisitor { - type Error: Error; - - #[inline] - fn visit(&mut self) -> Result, Self::Error> - where K: Deserialize, - V: Deserialize, - { - match try!(self.visit_key()) { - Some(key) => { - let value = try!(self.visit_value()); - Ok(Some((key, value))) - } - None => Ok(None) - } - } - - fn visit_key(&mut self) -> Result, Self::Error> - where K: Deserialize; - - fn visit_value(&mut self) -> Result - where V: Deserialize; - - fn end(&mut self) -> Result<(), Self::Error>; - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) - } -} - -impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor { - type Error = V_::Error; - - #[inline] - fn visit(&mut self) -> Result, V_::Error> - where K: Deserialize, - V: Deserialize, - { - (**self).visit() - } - - #[inline] - fn visit_key(&mut self) -> Result, V_::Error> - where K: Deserialize - { - (**self).visit_key() - } - - #[inline] - fn visit_value(&mut self) -> Result - where V: Deserialize - { - (**self).visit_value() - } - - #[inline] - fn end(&mut self) -> Result<(), V_::Error> { - (**self).end() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (**self).size_hint() - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait EnumVisitor { - type Error: Error; - - fn visit_unit(&mut self) -> Result<(), Self::Error> { - Err(Error::syntax_error()) - } - - fn visit_seq(&mut self, _visitor: V) -> Result - where V: EnumSeqVisitor, - { - Err(Error::syntax_error()) - } - - fn visit_map(&mut self, _visitor: V) -> Result - where V: EnumMapVisitor, - { - Err(Error::syntax_error()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -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; -} - -/////////////////////////////////////////////////////////////////////////////// - -struct UnitVisitor; - -impl Visitor for UnitVisitor { - type Value = (); - - fn visit_unit(&mut self) -> Result<(), E> - where E: Error, - { - Ok(()) - } - - fn visit_seq(&mut self, mut visitor: V) -> Result<(), V::Error> - where V: SeqVisitor, - { - visitor.end() - } -} - -impl Deserialize for () { - fn deserialize(deserializer: &mut D) -> Result<(), D::Error> - where D: Deserializer, - { - deserializer.visit(UnitVisitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -struct BoolVisitor; - -impl Visitor for BoolVisitor { - type Value = bool; - - fn visit_bool(&mut self, v: bool) -> Result - where E: Error, - { - Ok(v) - } -} - -impl Deserialize for bool { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer, - { - deserializer.visit(BoolVisitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -macro_rules! impl_deserialize_num_method { - ($src_ty:ty, $method:ident, $from_method:ident) => { - #[inline] - fn $method(&mut self, v: $src_ty) -> Result - where E: Error, - { - match FromPrimitive::$from_method(v) { - Some(v) => Ok(v), - None => Err(Error::syntax_error()), - } - } - } -} - -pub struct PrimitiveVisitor { - marker: PhantomData, -} - -impl PrimitiveVisitor { - #[inline] - pub fn new() -> Self { - PrimitiveVisitor { - marker: PhantomData, - } - } -} - -impl< - T: Deserialize + FromPrimitive -> self::Visitor for PrimitiveVisitor { - type Value = T; - - impl_deserialize_num_method!(isize, visit_isize, from_isize); - impl_deserialize_num_method!(i8, visit_i8, from_i8); - impl_deserialize_num_method!(i16, visit_i16, from_i16); - impl_deserialize_num_method!(i32, visit_i32, from_i32); - impl_deserialize_num_method!(i64, visit_i64, from_i64); - impl_deserialize_num_method!(usize, visit_usize, from_usize); - impl_deserialize_num_method!(u8, visit_u8, from_u8); - impl_deserialize_num_method!(u16, visit_u16, from_u16); - impl_deserialize_num_method!(u32, visit_u32, from_u32); - impl_deserialize_num_method!(u64, visit_u64, from_u64); - impl_deserialize_num_method!(f32, visit_f32, from_f32); - impl_deserialize_num_method!(f64, visit_f64, from_f64); -} - -macro_rules! impl_deserialize_num { - ($ty:ty) => { - impl Deserialize for $ty { - #[inline] - fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> - where D: Deserializer, - { - deserializer.visit(PrimitiveVisitor::new()) - } - } - } -} - -impl_deserialize_num!(isize); -impl_deserialize_num!(i8); -impl_deserialize_num!(i16); -impl_deserialize_num!(i32); -impl_deserialize_num!(i64); -impl_deserialize_num!(usize); -impl_deserialize_num!(u8); -impl_deserialize_num!(u16); -impl_deserialize_num!(u32); -impl_deserialize_num!(u64); -impl_deserialize_num!(f32); -impl_deserialize_num!(f64); - -/////////////////////////////////////////////////////////////////////////////// - -struct CharVisitor; - -impl Visitor for CharVisitor { - type Value = char; - - #[inline] - fn visit_char(&mut self, v: char) -> Result - where E: Error, - { - Ok(v) - } - - #[inline] - fn visit_str(&mut self, v: &str) -> Result - where E: Error, - { - let mut iter = v.chars(); - if let Some(v) = iter.next() { - if iter.next().is_some() { - Err(Error::syntax_error()) - } else { - Ok(v) - } - } else { - Err(Error::end_of_stream_error()) - } - } -} - -impl Deserialize for char { - #[inline] - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer, - { - deserializer.visit(CharVisitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -struct StringVisitor; - -impl Visitor for StringVisitor { - type Value = String; - - fn visit_str(&mut self, v: &str) -> Result - where E: Error, - { - Ok(v.to_string()) - } - - fn visit_string(&mut self, v: String) -> Result - where E: Error, - { - Ok(v) - } -} - -impl Deserialize for String { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer, - { - deserializer.visit(StringVisitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -struct OptionVisitor { - marker: PhantomData, -} - -impl< - T: Deserialize, -> Visitor for OptionVisitor { - type Value = Option; - - #[inline] - fn visit_none(&mut self) -> Result, E> - where E: Error, - { - Ok(None) - } - - #[inline] - fn visit_some(&mut self, deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - Ok(Some(try!(Deserialize::deserialize(deserializer)))) - } -} - -impl Deserialize for Option where T: Deserialize { - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit_option(OptionVisitor { marker: PhantomData }) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct VecVisitor { - marker: PhantomData, -} - -impl VecVisitor { - pub fn new() -> Self { - VecVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for VecVisitor where T: Deserialize { - type Value = Vec; - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> - where V: SeqVisitor, - { - let (len, _) = visitor.size_hint(); - let mut values = Vec::with_capacity(len); - - while let Some(value) = try!(visitor.visit()) { - values.push(value); - } - - Ok(values) - } -} - -impl Deserialize for Vec { - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(VecVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -macro_rules! tuple_impls { - () => {}; - ($($visitor:ident => ($($name:ident),+),)+) => { - $( - struct $visitor<$($name,)+> { - marker: PhantomData<($($name,)+)>, - } - - impl< - $($name: Deserialize,)+ - > Visitor for $visitor<$($name,)+> { - type Value = ($($name,)+); - - #[inline] - #[allow(non_snake_case)] - fn visit_seq(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error> - where V: SeqVisitor, - { - $( - let $name = match try!(visitor.visit()) { - Some(value) => value, - None => { return Err(Error::end_of_stream_error()); } - }; - )+; - - try!(visitor.end()); - - Ok(($($name,)+)) - } - } - - impl< - $($name: Deserialize),+ - > Deserialize for ($($name,)+) { - #[inline] - fn deserialize(deserializer: &mut D) -> Result<($($name,)+), D::Error> - where D: Deserializer, - { - deserializer.visit($visitor { marker: PhantomData }) - } - } - )+ - } -} - -tuple_impls! { - TupleVisitor1 => (T0), - TupleVisitor2 => (T0, T1), - TupleVisitor3 => (T0, T1, T2), - TupleVisitor4 => (T0, T1, T2, T3), - TupleVisitor5 => (T0, T1, T2, T3, T4), - TupleVisitor6 => (T0, T1, T2, T3, T4, T5), - TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), - TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), - TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), - TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), - TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), - TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct HashMapVisitor { - marker: PhantomData>, -} - -impl HashMapVisitor { - #[inline] - pub fn new() -> Self { - HashMapVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for HashMapVisitor - where K: Deserialize + Eq + Hash, - V: Deserialize, -{ - type Value = HashMap; - - #[inline] - fn visit_map(&mut self, mut visitor: V_) -> Result, V_::Error> - where V_: MapVisitor, - { - let (len, _) = visitor.size_hint(); - let mut values = HashMap::with_capacity(len); - - while let Some((key, value)) = try!(visitor.visit()) { - values.insert(key, value); - } - - Ok(values) - } -} - -impl Deserialize for HashMap - where K: Deserialize + Eq + Hash, - V: Deserialize, -{ - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(HashMapVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct BTreeMapVisitor { - marker: PhantomData>, -} - -impl BTreeMapVisitor { - #[inline] - pub fn new() -> Self { - BTreeMapVisitor { - marker: PhantomData, - } - } -} - -impl Visitor for BTreeMapVisitor - where K: Deserialize + Ord, - V: Deserialize -{ - type Value = BTreeMap; - - #[inline] - fn visit_map(&mut self, mut visitor: Visitor) -> Result, Visitor::Error> - where Visitor: MapVisitor, - { - let mut values = BTreeMap::new(); - - while let Some((key, value)) = try!(visitor.visit()) { - values.insert(key, value); - } - - Ok(values) - } -} - -impl< - K: Deserialize + Eq + Ord, - V: Deserialize, -> Deserialize for BTreeMap { - fn deserialize(deserializer: &mut D) -> Result, D::Error> - where D: Deserializer, - { - deserializer.visit(BTreeMapVisitor::new()) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -struct PathBufVisitor; - -impl Visitor for PathBufVisitor { - type Value = path::PathBuf; - - fn visit_str(&mut self, v: &str) -> Result - where E: Error, - { - Ok(path::PathBuf::new(&v)) - } - - fn visit_string(&mut self, v: String) -> Result - where E: Error, - { - self.visit_str(&v) - } -} - -impl Deserialize for path::PathBuf { - fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer, - { - deserializer.visit(PathBufVisitor) - } -} diff --git a/serde2/src/json/builder.rs b/serde2/src/json/builder.rs deleted file mode 100644 index 3db2c4ed..00000000 --- a/serde2/src/json/builder.rs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::collections::BTreeMap; - -use ser::{self, Serialize}; -use json::value::{self, Value}; - -pub struct ArrayBuilder { - array: Vec, -} - -impl ArrayBuilder { - pub fn new() -> ArrayBuilder { - ArrayBuilder { array: Vec::new() } - } - - pub fn unwrap(self) -> Value { - Value::Array(self.array) - } - - pub fn push(mut self, v: T) -> ArrayBuilder { - self.array.push(value::to_value(&v)); - self - } - - pub fn push_array(mut self, f: F) -> ArrayBuilder where - F: FnOnce(ArrayBuilder) -> ArrayBuilder - { - let builder = ArrayBuilder::new(); - self.array.push(f(builder).unwrap()); - self - } - - pub fn push_object(mut self, f: F) -> ArrayBuilder where - F: FnOnce(ObjectBuilder) -> ObjectBuilder - { - let builder = ObjectBuilder::new(); - self.array.push(f(builder).unwrap()); - self - } -} - -pub struct ObjectBuilder { - object: BTreeMap, -} - -impl ObjectBuilder { - pub fn new() -> ObjectBuilder { - ObjectBuilder { object: BTreeMap::new() } - } - - pub fn unwrap(self) -> Value { - Value::Object(self.object) - } - - pub fn insert(mut self, k: String, v: V) -> ObjectBuilder { - self.object.insert(k, value::to_value(&v)); - self - } - - pub fn insert_array(mut self, key: String, f: F) -> ObjectBuilder where - F: FnOnce(ArrayBuilder) -> ArrayBuilder - { - let builder = ArrayBuilder::new(); - self.object.insert(key, f(builder).unwrap()); - self - } - - pub fn insert_object(mut self, key: String, f: F) -> ObjectBuilder where - F: FnOnce(ObjectBuilder) -> ObjectBuilder - { - let builder = ObjectBuilder::new(); - self.object.insert(key, f(builder).unwrap()); - self - } -} diff --git a/serde2/src/json/de.rs b/serde2/src/json/de.rs deleted file mode 100644 index f0f96edb..00000000 --- a/serde2/src/json/de.rs +++ /dev/null @@ -1,636 +0,0 @@ -use std::char; -use std::num::Float; -use unicode::str::Utf16Item; -use std::str; - -use de; -use super::error::{Error, ErrorCode}; - -pub struct Deserializer { - rdr: Iter, - ch: Option, - line: usize, - col: usize, - buf: Vec, -} - -impl Deserializer - where Iter: Iterator, -{ - /// Creates the JSON parser. - #[inline] - pub fn new(rdr: Iter) -> Deserializer { - let mut p = Deserializer { - rdr: rdr, - ch: Some(b'\x00'), - line: 1, - col: 0, - buf: Vec::with_capacity(128), - }; - p.bump(); - return p; - } - - #[inline] - pub fn end(&mut self) -> Result<(), Error> { - self.parse_whitespace(); - if self.eof() { - Ok(()) - } else { - Err(self.error(ErrorCode::TrailingCharacters)) - } - } - - fn eof(&self) -> bool { self.ch.is_none() } - - fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') } - - fn bump(&mut self) { - self.ch = self.rdr.next(); - - if self.ch_is(b'\n') { - self.line += 1; - self.col = 1; - } else { - self.col += 1; - } - } - - fn next_char(&mut self) -> Option { - self.bump(); - self.ch - } - - fn ch_is(&self, c: u8) -> bool { - self.ch == Some(c) - } - - fn error(&mut self, reason: ErrorCode) -> Error { - Error::SyntaxError(reason, self.line, self.col) - } - - fn parse_whitespace(&mut self) { - while self.ch_is(b' ') || - self.ch_is(b'\n') || - self.ch_is(b'\t') || - self.ch_is(b'\r') { self.bump(); } - } - - fn parse_value(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - self.parse_whitespace(); - - if self.eof() { - return Err(self.error(ErrorCode::EOFWhileParsingValue)); - } - - match self.ch_or_null() { - b'n' => { - try!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - b't' => { - try!(self.parse_ident(b"rue")); - visitor.visit_bool(true) - } - b'f' => { - try!(self.parse_ident(b"alse")); - visitor.visit_bool(false) - } - b'0' ... b'9' | b'-' => self.parse_number(visitor), - b'"' => { - try!(self.parse_string()); - let s = str::from_utf8(&self.buf).unwrap(); - visitor.visit_str(s) - } - b'[' => { - self.bump(); - visitor.visit_seq(SeqVisitor::new(self)) - } - b'{' => { - self.bump(); - visitor.visit_map(MapVisitor::new(self)) - } - _ => { - Err(self.error(ErrorCode::ExpectedSomeValue)) - } - } - } - - fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> { - if ident.iter().all(|c| Some(*c) == self.next_char()) { - self.bump(); - Ok(()) - } else { - Err(self.error(ErrorCode::ExpectedSomeIdent)) - } - } - - fn parse_number(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - let mut neg = 1; - - if self.ch_is(b'-') { - self.bump(); - neg = -1; - } - - let res = try!(self.parse_integer()); - - if self.ch_is(b'.') || self.ch_is(b'e') || self.ch_is(b'E') { - let neg = neg as f64; - let mut res = res as f64; - - if self.ch_is(b'.') { - res = try!(self.parse_decimal(res)); - } - - if self.ch_is(b'e') || self.ch_is(b'E') { - res = try!(self.parse_exponent(res)); - } - - visitor.visit_f64(neg * res) - } else { - visitor.visit_i64(neg * res) - } - } - - fn parse_integer(&mut self) -> Result { - let mut res = 0; - - match self.ch_or_null() { - b'0' => { - self.bump(); - - // There can be only one leading '0'. - match self.ch_or_null() { - b'0' ... b'9' => { - return Err(self.error(ErrorCode::InvalidNumber)); - } - _ => () - } - }, - b'1' ... b'9' => { - while !self.eof() { - match self.ch_or_null() { - c @ b'0' ... b'9' => { - res *= 10; - res += (c as i64) - (b'0' as i64); - self.bump(); - } - _ => break, - } - } - } - _ => { return Err(self.error(ErrorCode::InvalidNumber)); } - } - - Ok(res) - } - - fn parse_decimal(&mut self, res: f64) -> Result { - self.bump(); - - // Make sure a digit follows the decimal place. - match self.ch_or_null() { - b'0' ... b'9' => (), - _ => { return Err(self.error(ErrorCode::InvalidNumber)); } - } - - let mut res = res; - let mut dec = 1.0; - while !self.eof() { - match self.ch_or_null() { - c @ b'0' ... b'9' => { - dec /= 10.0; - res += (((c as u64) - (b'0' as u64)) as f64) * dec; - self.bump(); - } - _ => break, - } - } - - Ok(res) - } - - fn parse_exponent(&mut self, mut res: f64) -> Result { - self.bump(); - - let mut exp = 0; - let mut neg_exp = false; - - if self.ch_is(b'+') { - self.bump(); - } else if self.ch_is(b'-') { - self.bump(); - neg_exp = true; - } - - // Make sure a digit follows the exponent place. - match self.ch_or_null() { - b'0' ... b'9' => (), - _ => { return Err(self.error(ErrorCode::InvalidNumber)); } - } - while !self.eof() { - match self.ch_or_null() { - c @ b'0' ... b'9' => { - exp *= 10; - exp += (c as i32) - (b'0' as i32); - - self.bump(); - } - _ => break - } - } - - let exp: f64 = 10_f64.powi(exp); - if neg_exp { - res /= exp; - } else { - res *= exp; - } - - Ok(res) - } - - fn decode_hex_escape(&mut self) -> Result { - let mut i = 0; - let mut n = 0u16; - while i < 4 && !self.eof() { - self.bump(); - n = match self.ch_or_null() { - c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)), - b'a' | b'A' => n * 16_u16 + 10_u16, - b'b' | b'B' => n * 16_u16 + 11_u16, - b'c' | b'C' => n * 16_u16 + 12_u16, - b'd' | b'D' => n * 16_u16 + 13_u16, - b'e' | b'E' => n * 16_u16 + 14_u16, - b'f' | b'F' => n * 16_u16 + 15_u16, - _ => { return Err(self.error(ErrorCode::InvalidEscape)); } - }; - - i += 1; - } - - // Error out if we didn't parse 4 digits. - if i != 4 { - return Err(self.error(ErrorCode::InvalidEscape)); - } - - Ok(n) - } - - fn parse_string(&mut self) -> Result<(), Error> { - self.buf.clear(); - - let mut escape = false; - - loop { - let ch = match self.next_char() { - Some(ch) => ch, - None => { return Err(self.error(ErrorCode::EOFWhileParsingString)); } - }; - - if escape { - match ch { - b'"' => self.buf.push(b'"'), - b'\\' => self.buf.push(b'\\'), - b'/' => self.buf.push(b'/'), - b'b' => self.buf.push(b'\x08'), - b'f' => self.buf.push(b'\x0c'), - b'n' => self.buf.push(b'\n'), - b'r' => self.buf.push(b'\r'), - b't' => self.buf.push(b'\t'), - b'u' => { - let c = match try!(self.decode_hex_escape()) { - 0xDC00 ... 0xDFFF => { - return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape)); - } - - // Non-BMP characters are encoded as a sequence of - // two hex escapes, representing UTF-16 surrogates. - n1 @ 0xD800 ... 0xDBFF => { - let c1 = self.next_char(); - let c2 = self.next_char(); - match (c1, c2) { - (Some(b'\\'), Some(b'u')) => (), - _ => { - return Err(self.error(ErrorCode::UnexpectedEndOfHexEscape)); - } - } - - let buf = &[n1, try!(self.decode_hex_escape())]; - match ::unicode::str::utf16_items(buf).next() { - Some(Utf16Item::ScalarValue(c)) => c, - _ => { - return Err(self.error(ErrorCode::LoneLeadingSurrogateInHexEscape)); - } - } - } - - n => match char::from_u32(n as u32) { - Some(c) => c, - None => { - return Err(self.error(ErrorCode::InvalidUnicodeCodePoint)); - } - } - }; - - let buf = &mut [0; 4]; - let len = c.encode_utf8(buf).unwrap_or(0); - self.buf.extend(buf[..len].iter().map(|b| *b)); - } - _ => { - return Err(self.error(ErrorCode::InvalidEscape)); - } - } - escape = false; - } else { - match ch { - b'"' => { - self.bump(); - return Ok(()); - } - b'\\' => { - escape = true; - } - ch => { - self.buf.push(ch); - } - } - } - } - } - - fn parse_object_colon(&mut self) -> Result<(), Error> { - self.parse_whitespace(); - - if self.ch_is(b':') { - self.bump(); - Ok(()) - } else if self.eof() { - Err(self.error(ErrorCode::EOFWhileParsingObject)) - } else { - Err(self.error(ErrorCode::ExpectedColon)) - } - } -} - -impl de::Deserializer for Deserializer - where Iter: Iterator, -{ - type Error = Error; - - #[inline] - fn visit(&mut self, visitor: V) -> Result - where V: de::Visitor, - { - self.parse_value(visitor) - } - - #[inline] - fn visit_option(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - self.parse_whitespace(); - - if self.eof() { - return Err(self.error(ErrorCode::EOFWhileParsingValue)); - } - - if self.ch_is(b'n') { - try!(self.parse_ident(b"ull")); - visitor.visit_none() - } else { - visitor.visit_some(self) - } - } - - #[inline] - fn visit_enum(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - self.parse_whitespace(); - - if self.ch_is(b'{') { - self.bump(); - self.parse_whitespace(); - - try!(self.parse_string()); - try!(self.parse_object_colon()); - - let variant = str::from_utf8(&self.buf).unwrap().to_string(); - - let value = try!(visitor.visit_variant(&variant, EnumVisitor { - de: self, - })); - - self.parse_whitespace(); - - if self.ch_is(b'}') { - self.bump(); - Ok(value) - } else { - return Err(self.error(ErrorCode::ExpectedSomeValue)); - } - } else { - Err(self.error(ErrorCode::ExpectedSomeValue)) - } - } -} - -struct SeqVisitor<'a, Iter: 'a> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, Iter> SeqVisitor<'a, Iter> { - fn new(de: &'a mut Deserializer) -> Self { - SeqVisitor { - de: de, - first: true, - } - } -} - -impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter> - where Iter: Iterator -{ - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize, - { - self.de.parse_whitespace(); - - if self.de.ch_is(b']') { - self.de.bump(); - return Ok(None); - } - - if self.first { - self.first = false; - } else { - if self.de.ch_is(b',') { - self.de.bump(); - } else if self.de.eof() { - return Err(self.de.error(ErrorCode::EOFWhileParsingList)); - } else { - return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd)); - } - } - - let value = try!(de::Deserialize::deserialize(self.de)); - Ok(Some(value)) - } - - fn end(&mut self) -> Result<(), Error> { - self.de.parse_whitespace(); - - if self.de.ch_is(b']') { - self.de.bump(); - Ok(()) - } else if self.de.eof() { - Err(self.de.error(ErrorCode::EOFWhileParsingList)) - } else { - Err(self.de.error(ErrorCode::TrailingCharacters)) - } - } -} - -struct MapVisitor<'a, Iter: 'a> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, Iter> MapVisitor<'a, Iter> { - fn new(de: &'a mut Deserializer) -> Self { - MapVisitor { - de: de, - first: true, - } - } -} - -impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter> - where Iter: Iterator -{ - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where K: de::Deserialize, - { - self.de.parse_whitespace(); - - if self.de.ch_is(b'}') { - self.de.bump(); - return Ok(None); - } - - if self.first { - self.first = false; - } else { - if self.de.ch_is(b',') { - self.de.bump(); - self.de.parse_whitespace(); - } else if self.de.eof() { - return Err(self.de.error(ErrorCode::EOFWhileParsingObject)); - } else { - return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd)); - } - } - - if self.de.eof() { - return Err(self.de.error(ErrorCode::EOFWhileParsingValue)); - } - - if !self.de.ch_is(b'"') { - return Err(self.de.error(ErrorCode::KeyMustBeAString)); - } - - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - - fn visit_value(&mut self) -> Result - where V: de::Deserialize, - { - try!(self.de.parse_object_colon()); - - Ok(try!(de::Deserialize::deserialize(self.de))) - } - - fn end(&mut self) -> Result<(), Error> { - self.de.parse_whitespace(); - - if self.de.ch_is(b']') { - self.de.bump(); - Ok(()) - } else if self.de.eof() { - Err(self.de.error(ErrorCode::EOFWhileParsingList)) - } else { - Err(self.de.error(ErrorCode::TrailingCharacters)) - } - } -} - -struct EnumVisitor<'a, Iter: 'a> { - de: &'a mut Deserializer, -} - -impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter> - where Iter: Iterator, -{ - type Error = Error; - - fn visit_unit(&mut self) -> Result<(), Error> { - de::Deserialize::deserialize(self.de) - } - - fn visit_seq(&mut self, mut visitor: V) -> Result - where V: de::EnumSeqVisitor, - { - self.de.parse_whitespace(); - - if self.de.ch_is(b'[') { - self.de.bump(); - visitor.visit(SeqVisitor::new(self.de)) - } else { - Err(self.de.error(ErrorCode::ExpectedSomeValue)) - } - } - - fn visit_map(&mut self, mut visitor: V) -> Result - where V: de::EnumMapVisitor, - { - self.de.parse_whitespace(); - - if self.de.ch_is(b'{') { - self.de.bump(); - visitor.visit(MapVisitor::new(self.de)) - } else { - Err(self.de.error(ErrorCode::ExpectedSomeValue)) - } - } -} - -/// Decodes a json value from an `Iterator`. -pub fn from_iter(iter: I) -> Result - where I: Iterator, - T: de::Deserialize -{ - let mut de = Deserializer::new(iter); - let value = try!(de::Deserialize::deserialize(&mut de)); - - // Make sure the whole stream has been consumed. - try!(de.end()); - Ok(value) -} - -/// Decodes a json value from a string -pub fn from_str<'a, T>(s: &'a str) -> Result - where T: de::Deserialize -{ - from_iter(s.bytes()) -} diff --git a/serde2/src/json/error.rs b/serde2/src/json/error.rs deleted file mode 100644 index 430b0b04..00000000 --- a/serde2/src/json/error.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::error; -use std::fmt; -use std::io; - -use de; - -/// The errors that can arise while parsing a JSON stream. -#[derive(Copy, Clone, PartialEq)] -pub enum ErrorCode { - EOFWhileParsingList, - EOFWhileParsingObject, - EOFWhileParsingString, - EOFWhileParsingValue, - ExpectedColon, - ExpectedConversion, - ExpectedEnumEnd, - ExpectedEnumEndToken, - ExpectedEnumMapStart, - ExpectedEnumToken, - ExpectedEnumVariantString, - ExpectedListCommaOrEnd, - ExpectedName, - ExpectedObjectCommaOrEnd, - ExpectedSomeIdent, - ExpectedSomeValue, - InvalidEscape, - InvalidNumber, - InvalidUnicodeCodePoint, - KeyMustBeAString, - LoneLeadingSurrogateInHexEscape, - MissingField(&'static str), - NotFourDigit, - NotUtf8, - TrailingCharacters, - UnexpectedEndOfHexEscape, - UnknownVariant, - UnrecognizedHex, -} - -impl fmt::Debug for ErrorCode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use std::fmt::Debug; - - match *self { - //ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token), - ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f), - ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f), - ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f), - ErrorCode::EOFWhileParsingValue => "EOF While parsing value".fmt(f), - ErrorCode::ExpectedColon => "expected `:`".fmt(f), - ErrorCode::ExpectedConversion => "expected conversion".fmt(f), - ErrorCode::ExpectedEnumEnd => "expected enum end".fmt(f), - ErrorCode::ExpectedEnumEndToken => "expected enum map end".fmt(f), - ErrorCode::ExpectedEnumMapStart => "expected enum map start".fmt(f), - ErrorCode::ExpectedEnumToken => "expected enum token".fmt(f), - ErrorCode::ExpectedEnumVariantString => "expected variant".fmt(f), - ErrorCode::ExpectedListCommaOrEnd => "expected `,` or `]`".fmt(f), - ErrorCode::ExpectedName => "expected name".fmt(f), - ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f), - ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f), - ErrorCode::ExpectedSomeValue => "expected value".fmt(f), - //ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token), - ErrorCode::InvalidEscape => "invalid escape".fmt(f), - ErrorCode::InvalidNumber => "invalid number".fmt(f), - ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f), - ErrorCode::KeyMustBeAString => "key must be a string".fmt(f), - ErrorCode::LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape".fmt(f), - ErrorCode::MissingField(ref field) => write!(f, "missing field \"{}\"", field), - ErrorCode::NotFourDigit => "invalid \\u escape (not four digits)".fmt(f), - ErrorCode::NotUtf8 => "contents not utf-8".fmt(f), - ErrorCode::TrailingCharacters => "trailing characters".fmt(f), - ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f), - //ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name), - ErrorCode::UnknownVariant => "unknown variant".fmt(f), - ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f), - } - } -} - -#[derive(Clone, PartialEq, Debug)] -pub enum Error { - /// msg, line, col - SyntaxError(ErrorCode, usize, usize), - IoError(io::Error), - /* - ExpectedError(String, String), - */ - MissingFieldError(&'static str), - /* - UnknownVariantError(String), - */ -} - -impl error::Error for Error { - fn description(&self) -> &str { - match *self { - Error::SyntaxError(..) => "syntax error", - Error::IoError(ref error) => error.description(), - /* - Error::ExpectedError(ref expected, _) => &expected, - */ - Error::MissingFieldError(_) => "missing field", - /* - Error::UnknownVariantError(_) => "unknown variant", - */ - } - } - - fn cause(&self) -> Option<&error::Error> { - match *self { - Error::IoError(ref error) => Some(error), - _ => None, - } - } - -} - -impl fmt::Display for Error { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - match *self { - Error::SyntaxError(ref code, line, col) => { - write!(fmt, "{:?} at line {} column {}", code, line, col) - } - Error::IoError(ref error) => fmt::Display::fmt(error, fmt), - /* - Error::ExpectedError(ref expected, ref found) => { - Some(format!("expected {}, found {}", expected, found)) - } - */ - Error::MissingFieldError(ref field) => { - write!(fmt, "missing field {}", field) - } - /* - Error::UnknownVariantError(ref variant) => { - Some(format!("unknown variant {}", variant)) - } - */ - } - } -} - -impl error::FromError for Error { - fn from_error(error: io::Error) -> Error { - Error::IoError(error) - } -} - -impl de::Error for Error { - fn syntax_error() -> Error { - Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0) - } - - fn end_of_stream_error() -> Error { - Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0) - } - - fn missing_field_error(field: &'static str) -> Error { - Error::MissingFieldError(field) - } -} diff --git a/serde2/src/json/mod.rs b/serde2/src/json/mod.rs deleted file mode 100644 index 4c1c6716..00000000 --- a/serde2/src/json/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -pub use self::de::{Deserializer, from_str}; -pub use self::error::{Error, ErrorCode}; -pub use self::ser::{ - Serializer, - to_writer, - to_writer_pretty, - to_vec, - to_vec_pretty, - to_string, - to_string_pretty, - escape_str, -}; -pub use self::value::{Value, to_value, from_value}; - -pub mod builder; -pub mod de; -pub mod error; -pub mod ser; -pub mod value; diff --git a/serde2/src/json/ser.rs b/serde2/src/json/ser.rs deleted file mode 100644 index 092f1a1f..00000000 --- a/serde2/src/json/ser.rs +++ /dev/null @@ -1,457 +0,0 @@ -use std::{f32, f64}; -use std::io; -use std::num::{Float, FpCategory}; -use std::string::FromUtf8Error; - -use ser; - -/// A structure for implementing serialization to JSON. -pub struct Serializer { - writer: W, - format: Format, - current_indent: usize, - indent: usize, -} - -#[derive(Copy, PartialEq)] -enum Format { - Compact, - Pretty, -} - -impl Serializer { - /// Creates a new JSON visitr whose output will be written to the writer - /// specified. - #[inline] - pub fn new(writer: W) -> Serializer { - Serializer { - writer: writer, - format: Format::Compact, - current_indent: 0, - indent: 0, - } - } - - /// Creates a new JSON visitr whose output will be written to the writer - /// specified. - #[inline] - pub fn new_pretty(writer: W) -> Serializer { - Serializer { - writer: writer, - format: Format::Pretty, - current_indent: 0, - indent: 2, - } - } - - /// Unwrap the `Writer` from the `Serializer`. - #[inline] - pub fn into_inner(self) -> W { - self.writer - } -} - -impl ser::Serializer for Serializer { - type Value = (); - type Error = io::Error; - - #[inline] - fn visit(&mut self, value: &T) -> io::Result<()> - where T: ser::Serialize, - { - value.visit(&mut Visitor { - writer: &mut self.writer, - format: self.format, - current_indent: self.current_indent, - indent: self.indent, - }) - } -} - -struct Visitor<'a, W: 'a> { - writer: &'a mut W, - format: Format, - current_indent: usize, - indent: usize, -} - -impl<'a, W> Visitor<'a, W> where W: io::Write, { - fn serialize_sep(&mut self, first: bool) -> io::Result<()> { - match self.format { - Format::Compact => { - if first { - Ok(()) - } else { - self.writer.write_all(b",") - } - } - Format::Pretty => { - if first { - self.current_indent += self.indent; - try!(self.writer.write_all(b"\n")); - } else { - try!(self.writer.write_all(b",\n")); - } - - spaces(&mut self.writer, self.current_indent) - } - } - } - - fn serialize_colon(&mut self) -> io::Result<()> { - match self.format { - Format::Compact => self.writer.write_all(b":"), - Format::Pretty => self.writer.write_all(b": "), - } - } - - fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> { - if self.format == Format::Pretty && current_indent != self.current_indent { - self.current_indent -= self.indent; - try!(self.writer.write(b"\n")); - try!(spaces(&mut self.writer, self.current_indent)); - } - - self.writer.write_all(s) - } -} - -impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, { - type Value = (); - type Error = io::Error; - - #[inline] - fn visit_bool(&mut self, value: bool) -> io::Result<()> { - if value { - self.writer.write_all(b"true") - } else { - self.writer.write_all(b"false") - } - } - - #[inline] - fn visit_isize(&mut self, value: isize) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_i8(&mut self, value: i8) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_i16(&mut self, value: i16) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_i32(&mut self, value: i32) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_usize(&mut self, value: usize) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_u8(&mut self, value: u8) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_u16(&mut self, value: u16) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_u32(&mut self, value: u32) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_u64(&mut self, value: u64) -> io::Result<()> { - write!(self.writer, "{}", value) - } - - #[inline] - fn visit_f32(&mut self, value: f32) -> io::Result<()> { - fmt_f32_or_null(self.writer, value) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> io::Result<()> { - fmt_f64_or_null(self.writer, value) - } - - #[inline] - fn visit_char(&mut self, value: char) -> io::Result<()> { - escape_char(self.writer, value) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> io::Result<()> { - escape_str(self.writer, value) - } - - #[inline] - fn visit_none(&mut self) -> io::Result<()> { - self.visit_unit() - } - - #[inline] - fn visit_some(&mut self, value: V) -> io::Result<()> - where V: ser::Serialize - { - value.visit(self) - } - - #[inline] - fn visit_unit(&mut self) -> io::Result<()> { - self.writer.write_all(b"null") - } - - #[inline] - fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> { - let current_indent = self.current_indent; - - try!(self.writer.write_all(b"{")); - try!(self.serialize_sep(true)); - try!(self.visit_str(variant)); - try!(self.serialize_colon()); - try!(self.writer.write_all(b"[]")); - self.serialize_end(current_indent, b"}") - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> io::Result<()> - where V: ser::SeqVisitor, - { - let current_indent = self.current_indent; - - try!(self.writer.write_all(b"[")); - - while let Some(()) = try!(visitor.visit(self)) { } - - self.serialize_end(current_indent, b"]") - } - - #[inline] - fn visit_enum_seq(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()> - where V: ser::SeqVisitor, - { - let current_indent = self.current_indent; - - try!(self.writer.write_all(b"{")); - try!(self.serialize_sep(true)); - try!(self.visit_str(variant)); - try!(self.serialize_colon()); - try!(self.visit_seq(visitor)); - self.serialize_end(current_indent, b"}") - } - - #[inline] - fn visit_seq_elt(&mut self, first: bool, value: T) -> io::Result<()> - where T: ser::Serialize, - { - try!(self.serialize_sep(first)); - - value.visit(self) - } - - #[inline] - fn visit_map(&mut self, mut visitor: V) -> io::Result<()> - where V: ser::MapVisitor, - { - let current_indent = self.current_indent; - - try!(self.writer.write_all(b"{")); - - while let Some(()) = try!(visitor.visit(self)) { } - - self.serialize_end(current_indent, b"}") - } - - #[inline] - fn visit_enum_map(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()> - where V: ser::MapVisitor, - { - let current_indent = self.current_indent; - - try!(self.writer.write_all(b"{")); - try!(self.serialize_sep(true)); - try!(self.visit_str(variant)); - try!(self.serialize_colon()); - try!(self.visit_map(visitor)); - self.serialize_end(current_indent, b"}") - } - - #[inline] - fn visit_map_elt(&mut self, first: bool, key: K, value: V) -> io::Result<()> - where K: ser::Serialize, - V: ser::Serialize, - { - try!(self.serialize_sep(first)); - try!(key.visit(self)); - try!(self.serialize_colon()); - value.visit(self) - } -} - -#[inline] -pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> io::Result<()> - where W: io::Write -{ - try!(wr.write_all(b"\"")); - - let mut start = 0; - - for (i, byte) in bytes.iter().enumerate() { - let escaped = match *byte { - b'"' => b"\\\"", - b'\\' => b"\\\\", - b'\x08' => b"\\b", - b'\x0c' => b"\\f", - b'\n' => b"\\n", - b'\r' => b"\\r", - b'\t' => b"\\t", - _ => { continue; } - }; - - if start < i { - try!(wr.write_all(&bytes[start..i])); - } - - try!(wr.write_all(escaped)); - - start = i + 1; - } - - if start != bytes.len() { - try!(wr.write_all(&bytes[start..])); - } - - try!(wr.write_all(b"\"")); - Ok(()) -} - -#[inline] -pub fn escape_str(wr: &mut W, value: &str) -> io::Result<()> - where W: io::Write -{ - escape_bytes(wr, value.as_bytes()) -} - -#[inline] -fn escape_char(wr: &mut W, value: char) -> io::Result<()> - where W: io::Write -{ - let buf = &mut [0; 4]; - value.encode_utf8(buf); - escape_bytes(wr, buf) -} - -fn fmt_f32_or_null(wr: &mut W, value: f32) -> io::Result<()> - where W: io::Write -{ - match value.classify() { - FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"), - _ => wr.write_all(f32::to_str_digits(value, 6).as_bytes()), - } -} - -fn fmt_f64_or_null(wr: &mut W, value: f64) -> io::Result<()> - where W: io::Write -{ - match value.classify() { - FpCategory::Nan | FpCategory::Infinite => wr.write_all(b"null"), - _ => wr.write_all(f64::to_str_digits(value, 6).as_bytes()), - } -} - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_writer(writer: &mut W, value: &T) -> io::Result<()> - where W: io::Write, - T: ser::Serialize, -{ - let mut ser = Serializer::new(writer); - try!(ser::Serializer::visit(&mut ser, value)); - Ok(()) -} - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_writer_pretty(writer: &mut W, value: &T) -> io::Result<()> - where W: io::Write, - T: ser::Serialize, -{ - let mut ser = Serializer::new_pretty(writer); - try!(ser::Serializer::visit(&mut ser, value)); - Ok(()) -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec(value: &T) -> Vec - where T: ser::Serialize, -{ - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let mut writer = Vec::with_capacity(128); - to_writer(&mut writer, value).unwrap(); - writer -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec_pretty(value: &T) -> Vec - where T: ser::Serialize, -{ - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let mut writer = Vec::with_capacity(128); - to_writer_pretty(&mut writer, value).unwrap(); - writer -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string(value: &T) -> Result - where T: ser::Serialize -{ - let vec = to_vec(value); - String::from_utf8(vec) -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string_pretty(value: &T) -> Result - where T: ser::Serialize -{ - let vec = to_vec_pretty(value); - String::from_utf8(vec) -} - -fn spaces(wr: &mut W, mut n: usize) -> io::Result<()> - where W: io::Write, -{ - const LEN: usize = 16; - const BUF: &'static [u8; LEN] = &[b' '; 16]; - - while n >= LEN { - try!(wr.write_all(BUF)); - n -= LEN; - } - - if n > 0 { - wr.write_all(&BUF[..n]) - } else { - Ok(()) - } -} diff --git a/serde2/src/json/value.rs b/serde2/src/json/value.rs deleted file mode 100644 index b7698d96..00000000 --- a/serde2/src/json/value.rs +++ /dev/null @@ -1,604 +0,0 @@ -use std::collections::{BTreeMap, btree_map}; -use std::fmt; -use std::io; -use std::str; -use std::vec; - -use de; -use ser; -use super::error::Error; - -#[derive(Clone, PartialEq)] -pub enum Value { - Null, - Bool(bool), - I64(i64), - F64(f64), - String(String), - Array(Vec), - Object(BTreeMap), -} - -impl ser::Serialize for Value { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: ser::Visitor, - { - match *self { - Value::Null => visitor.visit_unit(), - Value::Bool(v) => visitor.visit_bool(v), - Value::I64(v) => visitor.visit_i64(v), - Value::F64(v) => visitor.visit_f64(v), - Value::String(ref v) => visitor.visit_str(&v), - Value::Array(ref v) => v.visit(visitor), - Value::Object(ref v) => v.visit(visitor), - } - } -} - -impl de::Deserialize for Value { - #[inline] - fn deserialize(deserializer: &mut D) -> Result - where D: de::Deserializer, - { - struct ValueVisitor; - - impl de::Visitor for ValueVisitor { - type Value = Value; - - #[inline] - fn visit_bool(&mut self, value: bool) -> Result { - Ok(Value::Bool(value)) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> Result { - Ok(Value::I64(value)) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> Result { - Ok(Value::F64(value)) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> Result - where E: de::Error, - { - self.visit_string(value.to_string()) - } - - #[inline] - fn visit_string(&mut self, value: String) -> Result { - Ok(Value::String(value)) - } - - #[inline] - fn visit_none(&mut self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_some(&mut self, deserializer: &mut D) -> Result - where D: de::Deserializer, - { - de::Deserialize::deserialize(deserializer) - } - - #[inline] - fn visit_unit(&mut self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_seq(&mut self, visitor: V) -> Result - where V: de::SeqVisitor, - { - let values = try!(de::VecVisitor::new().visit_seq(visitor)); - Ok(Value::Array(values)) - } - - #[inline] - fn visit_map(&mut self, visitor: V) -> Result - where V: de::MapVisitor, - { - let values = try!(de::BTreeMapVisitor::new().visit_map(visitor)); - Ok(Value::Object(values)) - } - } - - deserializer.visit(ValueVisitor) - } -} - -struct WriterFormatter<'a, 'b: 'a> { - inner: &'a mut fmt::Formatter<'b>, -} - -impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { - fn write(&mut self, buf: &[u8]) -> io::Result { - match self.inner.write_str(str::from_utf8(buf).unwrap()) { - Ok(_) => Ok(buf.len()), - Err(_) => Err(io::Error::last_os_error()), - } - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl fmt::Debug for Value { - /// Serializes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut wr = WriterFormatter { inner: f }; - super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) - } -} - -#[derive(Debug)] -enum State { - Value(Value), - Array(Vec), - Object(BTreeMap), -} - -pub struct Serializer { - state: Vec, -} - -impl Serializer { - pub fn new() -> Serializer { - Serializer { - state: Vec::with_capacity(4), - } - } - - pub fn unwrap(mut self) -> Value { - match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - } - } -} - -impl ser::Serializer for Serializer { - type Value = (); - type Error = (); - - #[inline] - fn visit(&mut self, value: &T) -> Result<(), ()> - where T: ser::Serialize, - { - try!(value.visit(self)); - Ok(()) - } -} - -impl ser::Visitor for Serializer { - type Value = (); - type Error = (); - - #[inline] - fn visit_bool(&mut self, value: bool) -> Result<(), ()> { - self.state.push(State::Value(Value::Bool(value))); - Ok(()) - } - - #[inline] - fn visit_i64(&mut self, value: i64) -> Result<(), ()> { - self.state.push(State::Value(Value::I64(value))); - Ok(()) - } - - #[inline] - fn visit_u64(&mut self, value: u64) -> Result<(), ()> { - self.state.push(State::Value(Value::I64(value as i64))); - Ok(()) - } - - #[inline] - fn visit_f64(&mut self, value: f64) -> Result<(), ()> { - self.state.push(State::Value(Value::F64(value as f64))); - Ok(()) - } - - #[inline] - fn visit_char(&mut self, value: char) -> Result<(), ()> { - self.state.push(State::Value(Value::String(value.to_string()))); - Ok(()) - } - - #[inline] - fn visit_str(&mut self, value: &str) -> Result<(), ()> { - self.state.push(State::Value(Value::String(value.to_string()))); - Ok(()) - } - - #[inline] - fn visit_none(&mut self) -> Result<(), ()> { - self.visit_unit() - } - - #[inline] - fn visit_some(&mut self, value: V) -> Result<(), ()> - where V: ser::Serialize, - { - value.visit(self) - } - - #[inline] - fn visit_unit(&mut self) -> Result<(), ()> { - self.state.push(State::Value(Value::Null)); - Ok(()) - } - - #[inline] - fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> { - let mut values = BTreeMap::new(); - values.insert(variant.to_string(), Value::Array(vec![])); - - self.state.push(State::Value(Value::Object(values))); - - Ok(()) - } - - #[inline] - fn visit_seq(&mut self, mut visitor: V) -> Result<(), ()> - where V: ser::SeqVisitor, - { - let len = match visitor.size_hint() { - (_, Some(len)) => len, - (len, None) => len, - }; - - let values = Vec::with_capacity(len); - - self.state.push(State::Array(values)); - - while let Some(()) = try!(visitor.visit(self)) { } - - let values = match self.state.pop().unwrap() { - State::Array(values) => values, - state => panic!("Expected array, found {:?}", state), - }; - - self.state.push(State::Value(Value::Array(values))); - - Ok(()) - } - - #[inline] - fn visit_enum_seq(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()> - where V: ser::SeqVisitor, - { - try!(self.visit_seq(visitor)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - let mut object = BTreeMap::new(); - - object.insert(variant.to_string(), value); - - self.state.push(State::Value(Value::Object(object))); - - Ok(()) - } - - #[inline] - fn visit_seq_elt(&mut self, _first: bool, value: T) -> Result<(), ()> - where T: ser::Serialize, - { - try!(value.visit(self)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - match *self.state.last_mut().unwrap() { - State::Array(ref mut values) => { values.push(value); } - ref state => panic!("expected array, found {:?}", state), - } - - Ok(()) - } - - #[inline] - fn visit_map(&mut self, mut visitor: V) -> Result<(), ()> - where V: ser::MapVisitor, - { - let values = BTreeMap::new(); - - self.state.push(State::Object(values)); - - while let Some(()) = try!(visitor.visit(self)) { } - - let values = match self.state.pop().unwrap() { - State::Object(values) => values, - state => panic!("expected object, found {:?}", state), - }; - - self.state.push(State::Value(Value::Object(values))); - - Ok(()) - } - - #[inline] - fn visit_enum_map(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()> - where V: ser::MapVisitor, - { - try!(self.visit_map(visitor)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - let mut object = BTreeMap::new(); - - object.insert(variant.to_string(), value); - - self.state.push(State::Value(Value::Object(object))); - - Ok(()) - } - - #[inline] - fn visit_map_elt(&mut self, _first: bool, key: K, value: V) -> Result<(), ()> - where K: ser::Serialize, - V: ser::Serialize, - { - try!(key.visit(self)); - - let key = match self.state.pop().unwrap() { - State::Value(Value::String(value)) => value, - state => panic!("expected key, found {:?}", state), - }; - - try!(value.visit(self)); - - let value = match self.state.pop().unwrap() { - State::Value(value) => value, - state => panic!("expected value, found {:?}", state), - }; - - match *self.state.last_mut().unwrap() { - State::Object(ref mut values) => { values.insert(key, value); } - ref state => panic!("expected object, found {:?}", state), - } - - Ok(()) - } -} - -pub struct Deserializer { - value: Option, -} - -impl Deserializer { - /// Creates a new deserializer instance for deserializing the specified JSON value. - pub fn new(value: Value) -> Deserializer { - Deserializer { - value: Some(value), - } - } -} - -impl de::Deserializer for Deserializer { - type Error = Error; - - #[inline] - fn visit(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - let value = match self.value.take() { - Some(value) => value, - None => { return Err(de::Error::end_of_stream_error()); } - }; - - match value { - Value::Null => visitor.visit_unit(), - Value::Bool(v) => visitor.visit_bool(v), - Value::I64(v) => visitor.visit_i64(v), - Value::F64(v) => visitor.visit_f64(v), - Value::String(v) => visitor.visit_string(v), - Value::Array(v) => { - let len = v.len(); - visitor.visit_seq(SeqDeserializer { - de: self, - iter: v.into_iter(), - len: len, - }) - } - Value::Object(v) => { - let len = v.len(); - visitor.visit_map(MapDeserializer { - de: self, - iter: v.into_iter(), - value: None, - len: len, - }) - } - } - } - - #[inline] - fn visit_option(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - match self.value { - Some(Value::Null) => visitor.visit_none(), - Some(_) => visitor.visit_some(self), - None => Err(de::Error::end_of_stream_error()), - } - } - - #[inline] - fn visit_enum(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - let value = match self.value.take() { - Some(Value::Object(value)) => value, - Some(_) => { return Err(de::Error::syntax_error()); } - None => { return Err(de::Error::end_of_stream_error()); } - }; - - let mut iter = value.into_iter(); - - let value = match iter.next() { - Some((variant, Value::Array(fields))) => { - let len = fields.len(); - try!(visitor.visit_variant(&variant, SeqDeserializer { - de: self, - iter: fields.into_iter(), - len: len, - })) - } - Some((variant, Value::Object(fields))) => { - let len = fields.len(); - try!(visitor.visit_variant(&variant, MapDeserializer { - de: self, - iter: fields.into_iter(), - value: None, - len: len, - })) - } - Some(_) => { return Err(de::Error::syntax_error()); } - None => { return Err(de::Error::syntax_error()); } - }; - - match iter.next() { - Some(_) => Err(de::Error::syntax_error()), - None => Ok(value) - } - } -} - -struct SeqDeserializer<'a> { - de: &'a mut Deserializer, - iter: vec::IntoIter, - len: usize, -} - -impl<'a> de::SeqVisitor for SeqDeserializer<'a> { - type Error = Error; - - fn visit(&mut self) -> Result, Error> - where T: de::Deserialize - { - match self.iter.next() { - Some(value) => { - self.len -= 1; - self.de.value = Some(value); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => Ok(None), - } - } - - fn end(&mut self) -> Result<(), Error> { - if self.len == 0 { - Ok(()) - } else { - Err(de::Error::end_of_stream_error()) - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> de::EnumVisitor for SeqDeserializer<'a> { - type Error = Error; - - fn visit_unit(&mut self) -> Result<(), Error> { - if self.len == 0 { - Ok(()) - } else { - Err(de::Error::syntax_error()) - } - } - - fn visit_seq(&mut self, mut visitor: V) -> Result - where V: de::EnumSeqVisitor, - { - visitor.visit(self) - } -} - -struct MapDeserializer<'a> { - de: &'a mut Deserializer, - iter: btree_map::IntoIter, - value: Option, - len: usize, -} - -impl<'a> de::MapVisitor for MapDeserializer<'a> { - type Error = Error; - - fn visit_key(&mut self) -> Result, Error> - where T: de::Deserialize - { - match self.iter.next() { - Some((key, value)) => { - self.len -= 1; - self.value = Some(value); - self.de.value = Some(Value::String(key)); - Ok(Some(try!(de::Deserialize::deserialize(self.de)))) - } - None => Ok(None), - } - } - - fn visit_value(&mut self) -> Result - where T: de::Deserialize - { - let value = self.value.take().unwrap(); - self.de.value = Some(value); - Ok(try!(de::Deserialize::deserialize(self.de))) - } - - fn end(&mut self) -> Result<(), Error> { - if self.len == 0 { - Ok(()) - } else { - Err(de::Error::end_of_stream_error()) - } - } - - fn size_hint(&self) -> (usize, Option) { - (self.len, Some(self.len)) - } -} - -impl<'a> de::EnumVisitor for MapDeserializer<'a> { - type Error = Error; - - fn visit_map(&mut self, mut visitor: V) -> Result - where V: de::EnumMapVisitor, - { - visitor.visit(self) - } -} - -/// Shortcut function to encode a `T` into a JSON `Value` -pub fn to_value(value: &T) -> Value - where T: ser::Serialize -{ - let mut ser = Serializer::new(); - ser::Serializer::visit(&mut ser, value).ok().unwrap(); - ser.unwrap() -} - -/// Shortcut function to decode a JSON `Value` into a `T` -pub fn from_value(value: Value) -> Result - where T: de::Deserialize -{ - let mut de = Deserializer::new(value); - de::Deserialize::deserialize(&mut de) -} diff --git a/serde2/src/lib.rs b/serde2/src/lib.rs deleted file mode 100644 index 102a272b..00000000 --- a/serde2/src/lib.rs +++ /dev/null @@ -1,10 +0,0 @@ -#![feature(core, io, path, std_misc, unicode)] - -extern crate unicode; - -pub use ser::{Serialize, Serializer}; -pub use de::{Deserialize, Deserializer, Error}; - -pub mod ser; -pub mod de; -pub mod json; diff --git a/serde2/src/ser.rs b/serde2/src/ser.rs deleted file mode 100644 index 2efb786a..00000000 --- a/serde2/src/ser.rs +++ /dev/null @@ -1,660 +0,0 @@ -use std::collections::hash_state::HashState; -use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use std::hash::Hash; -use std::path; -use std::rc::Rc; -use std::str; -use std::sync::Arc; - -/////////////////////////////////////////////////////////////////////////////// - -pub trait Serialize { - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor; -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait Serializer { - type Value; - type Error; - - fn visit(&mut self, value: &T) -> Result - where T: Serialize; -} - -/////////////////////////////////////////////////////////////////////////////// - -pub trait Visitor { - type Value; - type Error; - - fn visit_bool(&mut self, v: bool) -> Result; - - #[inline] - fn visit_isize(&mut self, v: isize) -> Result { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i8(&mut self, v: i8) -> Result { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i16(&mut self, v: i16) -> Result { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i32(&mut self, v: i32) -> Result { - self.visit_i64(v as i64) - } - - #[inline] - fn visit_i64(&mut self, v: i64) -> Result; - - #[inline] - fn visit_usize(&mut self, v: usize) -> Result { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u8(&mut self, v: u8) -> Result { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u16(&mut self, v: u16) -> Result { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u32(&mut self, v: u32) -> Result { - self.visit_u64(v as u64) - } - - #[inline] - fn visit_u64(&mut self, v: u64) -> Result; - - #[inline] - fn visit_f32(&mut self, v: f32) -> Result { - self.visit_f64(v as f64) - } - - fn visit_f64(&mut self, v: f64) -> Result; - - #[inline] - fn visit_char(&mut self, v: char) -> Result { - // 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()) - } - - fn visit_str(&mut self, value: &str) -> Result; - - fn visit_unit(&mut self) -> Result; - - #[inline] - fn visit_named_unit(&mut self, _name: &str) -> Result { - self.visit_unit() - } - - #[inline] - fn visit_enum_unit(&mut self, - _name: &str, - _variant: &str) -> Result { - self.visit_unit() - } - - fn visit_none(&mut self) -> Result; - - fn visit_some(&mut self, value: V) -> Result - where V: Serialize; - - fn visit_seq(&mut self, visitor: V) -> Result - where V: SeqVisitor; - - #[inline] - fn visit_named_seq(&mut self, - _name: &'static str, - visitor: V) -> Result - where V: SeqVisitor, - { - self.visit_seq(visitor) - } - - #[inline] - fn visit_enum_seq(&mut self, - _name: &'static str, - _variant: &'static str, - visitor: V) -> Result - where V: SeqVisitor, - { - self.visit_seq(visitor) - } - - fn visit_seq_elt(&mut self, - first: bool, - value: T) -> Result - where T: Serialize; - - fn visit_map(&mut self, visitor: V) -> Result - where V: MapVisitor; - - #[inline] - fn visit_named_map(&mut self, - _name: &'static str, - visitor: V) -> Result - where V: MapVisitor, - { - self.visit_map(visitor) - } - - #[inline] - fn visit_enum_map(&mut self, - _name: &'static str, - _variant: &'static str, - visitor: V) -> Result - where V: MapVisitor, - { - self.visit_map(visitor) - } - - fn visit_map_elt(&mut self, - first: bool, - key: K, - value: V) -> Result - where K: Serialize, - V: Serialize; -} - -pub trait SeqVisitor { - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: Visitor; - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) - } -} - -pub trait MapVisitor { - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: Visitor; - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (0, None) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -macro_rules! impl_visit { - ($ty:ty, $method:ident) => { - impl Serialize for $ty { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - visitor.$method(*self) - } - } - } -} - -impl_visit!(bool, visit_bool); -impl_visit!(isize, visit_isize); -impl_visit!(i8, visit_i8); -impl_visit!(i16, visit_i16); -impl_visit!(i32, visit_i32); -impl_visit!(i64, visit_i64); -impl_visit!(usize, visit_usize); -impl_visit!(u8, visit_u8); -impl_visit!(u16, visit_u16); -impl_visit!(u32, visit_u32); -impl_visit!(u64, visit_u64); -impl_visit!(f32, visit_f32); -impl_visit!(f64, visit_f64); -impl_visit!(char, visit_char); - -/////////////////////////////////////////////////////////////////////////////// - -impl<'a> Serialize for &'a str { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - visitor.visit_str(*self) - } -} - -impl Serialize for String { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (&self[..]).visit(visitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl Serialize for Option where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - match *self { - Some(ref value) => visitor.visit_some(value), - None => visitor.visit_none(), - } - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct SeqIteratorVisitor { - iter: Iter, - first: bool, -} - -impl SeqIteratorVisitor - where Iter: Iterator -{ - #[inline] - pub fn new(iter: Iter) -> SeqIteratorVisitor { - SeqIteratorVisitor { - iter: iter, - first: true, - } - } -} - -impl SeqVisitor for SeqIteratorVisitor - where T: Serialize, - Iter: Iterator, -{ - #[inline] - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: Visitor, - { - let first = self.first; - self.first = false; - - match self.iter.next() { - Some(value) => { - let value = try!(visitor.visit_seq_elt(first, value)); - Ok(Some(value)) - } - None => Ok(None), - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl<'a, T> Serialize for &'a [T] - where T: Serialize, -{ - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) - } -} - -impl Serialize for Vec where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (&self[..]).visit(visitor) - } -} - -impl Serialize for BTreeSet where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) - } -} - -impl Serialize for HashSet - where T: Serialize + Eq + Hash, - S: HashState, -{ - #[inline] - fn visit(&self, visitor: &mut V) -> Result { - visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl Serialize for () { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - visitor.visit_unit() - } -} - -/////////////////////////////////////////////////////////////////////////////// - -// FIXME(rust #19630) Remove this work-around -macro_rules! e { - ($e:expr) => { $e } -} - -macro_rules! tuple_impls { - ($( - $TupleVisitor:ident ($len:expr, $($T:ident),+) { - $($state:pat => $idx:tt,)+ - } - )+) => { - $( - pub struct $TupleVisitor<'a, $($T: 'a),+> { - tuple: &'a ($($T,)+), - state: u8, - first: bool, - } - - impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> { - pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> { - $TupleVisitor { - tuple: tuple, - state: 0, - first: true, - } - } - } - - impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+> - where $($T: Serialize),+ - { - fn visit(&mut self, visitor: &mut V) -> Result, V::Error> - where V: Visitor, - { - let first = self.first; - self.first = false; - - match self.state { - $( - $state => { - self.state += 1; - Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx))))) - } - )+ - _ => { - Ok(None) - } - } - } - - fn size_hint(&self) -> (usize, Option) { - ($len, Some($len)) - } - } - - impl<$($T),+> Serialize for ($($T,)+) - where $($T: Serialize),+ - { - #[inline] - fn visit(&self, visitor: &mut V) -> Result { - visitor.visit_seq($TupleVisitor::new(self)) - } - } - )+ - } -} - -tuple_impls! { - TupleVisitor1 (1, T0) { - 0 => 0, - } - TupleVisitor2 (2, T0, T1) { - 0 => 0, - 1 => 1, - } - TupleVisitor3 (3, T0, T1, T2) { - 0 => 0, - 1 => 1, - 2 => 2, - } - TupleVisitor4 (4, T0, T1, T2, T3) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - } - TupleVisitor5 (5, T0, T1, T2, T3, T4) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - } - TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - } - TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - } - TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - } - TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - } - TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - } - TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - } - TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) { - 0 => 0, - 1 => 1, - 2 => 2, - 3 => 3, - 4 => 4, - 5 => 5, - 6 => 6, - 7 => 7, - 8 => 8, - 9 => 9, - 10 => 10, - 11 => 11, - } -} - -/////////////////////////////////////////////////////////////////////////////// - -pub struct MapIteratorVisitor { - iter: Iter, - first: bool, -} - -impl MapIteratorVisitor - where Iter: Iterator -{ - #[inline] - pub fn new(iter: Iter) -> MapIteratorVisitor { - MapIteratorVisitor { - iter: iter, - first: true, - } - } -} - -impl MapVisitor for MapIteratorVisitor - where K: Serialize, - V: Serialize, - I: Iterator, -{ - #[inline] - fn visit(&mut self, visitor: &mut V_) -> Result, V_::Error> - where V_: Visitor, - { - let first = self.first; - self.first = false; - - match self.iter.next() { - Some((key, value)) => { - let value = try!(visitor.visit_map_elt(first, key, value)); - Ok(Some(value)) - } - None => Ok(None) - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl Serialize for BTreeMap - where K: Serialize + Ord, - V: Serialize, -{ - #[inline] - fn visit(&self, visitor: &mut V_) -> Result { - visitor.visit_map(MapIteratorVisitor::new(self.iter())) - } -} - -impl Serialize for HashMap - where K: Serialize + Eq + Hash, - V: Serialize, - S: HashState, -{ - #[inline] - fn visit(&self, visitor: &mut V_) -> Result { - visitor.visit_map(MapIteratorVisitor::new(self.iter())) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl<'a, T> Serialize for &'a T where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (**self).visit(visitor) - } -} - -impl<'a, T> Serialize for &'a mut T where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (**self).visit(visitor) - } -} - -impl Serialize for Box where T: Serialize { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (**self).visit(visitor) - } -} - -impl Serialize for Rc where T: Serialize, { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (**self).visit(visitor) - } -} - -impl Serialize for Arc where T: Serialize, { - #[inline] - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - (**self).visit(visitor) - } -} - -/////////////////////////////////////////////////////////////////////////////// - -impl Serialize for path::Path { - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - self.to_str().unwrap().visit(visitor) - } -} - -impl Serialize for path::PathBuf { - fn visit(&self, visitor: &mut V) -> Result - where V: Visitor, - { - self.to_str().unwrap().visit(visitor) - } -} diff --git a/serde_macros/.gitignore b/serde_macros/.gitignore new file mode 100644 index 00000000..4fffb2f8 --- /dev/null +++ b/serde_macros/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/serde_macros/Cargo.toml b/serde_macros/Cargo.toml index f5be3304..a2e1ab8e 100644 --- a/serde_macros/Cargo.toml +++ b/serde_macros/Cargo.toml @@ -1,10 +1,13 @@ [package] name = "serde_macros" -version = "0.1.0" +version = "0.2.0" authors = ["Erick Tryzelaar "] -license = "MIT/Apache-2.0" -[[lib]] +[lib] name = "serde_macros" -path = "src/lib.rs" plugin = true + +[dependencies] +quasi = "0.1.0" +quasi_macros = "0.1.0" +aster = "0.1.2" diff --git a/serde_macros/src/lib.rs b/serde_macros/src/lib.rs index 3a1621a6..4b32f212 100644 --- a/serde_macros/src/lib.rs +++ b/serde_macros/src/lib.rs @@ -1,28 +1,24 @@ -#![crate_name = "serde_macros"] -#![crate_type = "dylib"] +#![feature(custom_derive, plugin, plugin_registrar, rustc_private, unboxed_closures)] +#![plugin(quasi_macros)] -#![feature(core, plugin_registrar, quote, unboxed_closures, rustc_private)] - -extern crate syntax; +extern crate aster; +extern crate quasi; extern crate rustc; +extern crate syntax; use syntax::ast::{ - Attribute, Ident, MetaItem, - MetaNameValue, + MetaItem_, Item, - ItemEnum, - ItemStruct, Expr, MutMutable, - LitStr, - StructField, - Variant, + StructDef, + EnumDef, }; use syntax::ast; -use syntax::attr; -use syntax::codemap::Span; +use syntax::ast_util; +use syntax::codemap::{Span, respan}; use syntax::ext::base::{ExtCtxt, Decorator, ItemDecorator}; use syntax::ext::build::AstBuilder; use syntax::ext::deriving::generic::{ @@ -42,11 +38,8 @@ use syntax::ext::deriving::generic::{ use syntax::ext::deriving::generic::ty::{ Borrowed, LifetimeBounds, - Literal, + Ty, Path, - Ptr, - Self_, - Tuple, borrowed_explicit_self, }; use syntax::parse::token; @@ -66,215 +59,626 @@ pub fn plugin_registrar(reg: &mut Registry) { Decorator(Box::new(expand_derive_deserialize))); } -fn expand_derive_serialize(cx: &mut ExtCtxt, - sp: Span, - mitem: &MetaItem, - item: &Item, - mut push: Box)>) { +fn expand_derive_serialize( + cx: &mut ExtCtxt, + sp: Span, + mitem: &MetaItem, + item: &Item, + push: &mut FnMut(P) +) { let inline = cx.meta_word(sp, token::InternedString::new("inline")); let attrs = vec!(cx.attribute(sp, inline)); let trait_def = TraitDef { span: sp, - attributes: vec!(), - path: Path::new_(vec!("serde", "ser", "Serialize"), None, - vec!(Box::new(Literal(Path::new_local("__S"))), - Box::new(Literal(Path::new_local("__E")))), true), + attributes: vec![], + path: Path::new(vec!["serde", "ser", "Serialize"]), additional_bounds: Vec::new(), - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__S", vec!(Path::new_( - vec!("serde", "ser", "Serializer"), None, - vec!(Box::new(Literal(Path::new_local("__E")))), true))), - ("__E", vec!())) - }, - methods: vec!( + generics: LifetimeBounds::empty(), + associated_types: vec![], + methods: vec![ MethodDef { - name: "serialize", - generics: LifetimeBounds::empty(), + name: "visit", + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec![ + ("__V", vec![Path::new(vec!["serde", "ser", "Visitor"])]), + ] + }, explicit_self: borrowed_explicit_self(), - args: vec!(Ptr(Box::new(Literal(Path::new_local("__S"))), - Borrowed(None, MutMutable))), - ret_ty: Literal( + args: vec![ + Ty::Ptr( + Box::new(Ty::Literal(Path::new_local("__V"))), + Borrowed(None, MutMutable), + ), + ], + ret_ty: Ty::Literal( Path::new_( vec!("std", "result", "Result"), None, - vec!( - Box::new(Tuple(Vec::new())), - Box::new(Literal(Path::new_local("__E"))) - ), + vec![ + Box::new(Ty::Literal(Path::new_(vec!["__V", "Value"], + None, + vec![], + false))), + Box::new(Ty::Literal(Path::new_(vec!["__V", "Error"], + None, + vec![], + false))), + ], true ) ), attributes: attrs, - combine_substructure: combine_substructure(Box::new( |a, b, c| { + combine_substructure: combine_substructure(Box::new(|a, b, c| { serialize_substructure(a, b, c, item) })), - }), - associated_types: vec!() + } + ] }; - trait_def.expand(cx, mitem, item, |item| push.call_mut((item,))) + trait_def.expand(cx, mitem, item, |item| push(item)) } -fn serialize_substructure(cx: &ExtCtxt, - span: Span, - substr: &Substructure, - item: &Item) -> P { - let serializer = substr.nonself_args[0].clone(); +fn serialize_substructure( + cx: &ExtCtxt, + span: Span, + substr: &Substructure, + item: &Item, +) -> P { + let builder = aster::AstBuilder::new().span(span); - match (&item.node, substr.fields) { - (&ItemStruct(ref definition, _), &Struct(ref fields)) => { - if fields.is_empty() { - // unit structs have no fields and need to return `Ok()` - quote_expr!(cx, Ok(())) - } else { - let type_name = cx.expr_str( - span, - token::get_ident(substr.type_ident) - ); - let len = fields.len(); + let visitor = substr.nonself_args[0].clone(); - let stmts: Vec> = definition.fields.iter() - .zip(fields.iter()) - .enumerate() - .map(|(i, (def, &FieldInfo { name, ref self_, span, .. }))| { - let serial_name = find_serial_name(def.node.attrs.iter()); - let name = match (serial_name, name) { - (Some(serial), _) => serial.clone(), - (None, Some(id)) => token::get_ident(id), - (None, None) => token::intern_and_get_ident(&format!("_field{}", i)[]), - }; + match (&item.node, &*substr.fields) { + (&ast::ItemStruct(ref struct_def, ref generics), &Struct(ref fields)) => { + let mut named_fields = vec![]; + let mut unnamed_fields = vec![]; - let name = cx.expr_str(span, name); + for field in fields { + match field.name { + Some(name) => { named_fields.push((name, field.span)); } + None => { unnamed_fields.push(field.span); } + } + } - quote_stmt!( - cx, - try!($serializer.serialize_struct_elt($name, &$self_)) - ) - }) - .collect(); - - quote_expr!(cx, { - try!($serializer.serialize_struct_start($type_name, $len)); - $stmts - $serializer.serialize_struct_end() - }) + match (named_fields.is_empty(), unnamed_fields.is_empty()) { + (true, true) => { + serialize_unit_struct( + cx, + &builder, + visitor, + substr.type_ident, + ) + } + (true, false) => { + serialize_tuple_struct( + cx, + &builder, + visitor, + substr.type_ident, + &unnamed_fields, + generics, + ) + } + (false, true) => { + serialize_struct( + cx, + &builder, + visitor, + substr.type_ident, + &named_fields, + struct_def, + generics, + ) + } + (false, false) => { + panic!("struct has named and unnamed fields") + } } } - (&ItemEnum(ref definition, _), &EnumMatching(_idx, variant, ref fields)) => { - let type_name = cx.expr_str( + (&ast::ItemEnum(_, ref generics), &EnumMatching(_idx, variant, ref fields)) => { + serialize_enum( + cx, span, - token::get_ident(substr.type_ident) - ); - let variant_name = cx.expr_str( - span, - token::get_ident(variant.node.name) - ); - let len = fields.len(); - - let stmts: Vec> = definition.variants.iter() - .zip(fields.iter()) - .map(|(def, &FieldInfo { ref self_, .. })| { - let _serial_name = find_serial_name(def.node.attrs.iter()); - quote_stmt!( - cx, - try!($serializer.serialize_enum_elt(&$self_)) - ) - }) - .collect(); - - quote_expr!(cx, { - try!($serializer.serialize_enum_start($type_name, $variant_name, $len)); - $stmts - $serializer.serialize_enum_end() - }) + &builder, + visitor, + substr.type_ident, + variant, + &fields, + generics, + ) } _ => cx.bug("expected Struct or EnumMatching in derive_serialize") } } -pub fn expand_derive_deserialize(cx: &mut ExtCtxt, - span: Span, - mitem: &MetaItem, - item: &Item, - mut push: Box)>) { +fn serialize_unit_struct( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + visitor: P, + type_ident: Ident +) -> P { + let type_name = builder.expr().str(type_ident); + + quote_expr!(cx, $visitor.visit_named_unit($type_name)) +} + +fn serialize_tuple_struct( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + visitor: P, + type_ident: Ident, + fields: &[Span], + generics: &ast::Generics +) -> P { + let type_name = builder.expr().str(type_ident); + let len = fields.len(); + + let arms: Vec = (0 .. fields.len()) + .map(|i| { + let first = builder.expr().bool(i == 0); + let expr = builder.expr() + .tup_field(i) + .field("value").self_(); + + quote_arm!(cx, + $i => { + self.state += 1; + let v = try!(visitor.visit_seq_elt($first, &$expr)); + Ok(Some(v)) + } + ) + }) + .collect(); + + let type_generics = builder.from_generics(generics.clone()) + .strip_bounds() + .build(); + + let visitor_impl_generics = builder.from_generics(generics.clone()) + .add_lifetime_bound("'__a") + .add_ty_param_bound( + builder.path().global().ids(&["serde", "ser", "Serialize"]).build() + ) + .lifetime_name("'__a") + .build(); + + let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) + .strip_bounds() + .build(); + + quote_expr!(cx, { + struct Visitor $visitor_impl_generics { + state: usize, + value: &'__a $type_ident $type_generics, + } + + impl $visitor_impl_generics ::serde::ser::SeqVisitor for Visitor $visitor_generics { + #[inline] + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: ::serde::ser::Visitor, + { + match self.state { + $arms + _ => Ok(None), + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let size = $len - (self.state as usize); + (size, Some(size)) + } + } + + $visitor.visit_named_seq($type_name, Visitor { + value: self, + state: 0, + }) + }) +} + +fn serialize_struct( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + visitor: P, + type_ident: Ident, + fields: &[(Ident, Span)], + struct_def: &StructDef, + generics: &ast::Generics +) -> P { + let type_name = builder.expr().str(type_ident); + let len = fields.len(); + + let aliases : Vec> = struct_def.fields.iter() + .map(field_alias) + .collect(); + + let arms: Vec = fields.iter() + .zip(aliases.iter()) + .enumerate() + .map(|(i, (&(name, _), alias_lit))| { + let first = builder.expr().bool(i == 0); + + let expr = match *alias_lit { + Some(lit) => builder.expr().build_lit(P(lit.clone())), + None => builder.expr().str(name), + }; + + quote_arm!(cx, + $i => { + self.state += 1; + let v = try!(visitor.visit_map_elt($first, $expr, &self.value.$name)); + Ok(Some(v)) + } + ) + }) + .collect(); + + let type_generics = builder.from_generics(generics.clone()) + .strip_bounds() + .build(); + + let visitor_impl_generics = builder.from_generics(generics.clone()) + .add_lifetime_bound("'__a") + .add_ty_param_bound( + builder.path().global().ids(&["serde", "ser", "Serialize"]).build() + ) + .lifetime_name("'__a") + .build(); + + let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) + .strip_bounds() + .build(); + + quote_expr!(cx, { + struct Visitor $visitor_impl_generics { + state: usize, + value: &'__a $type_ident $type_generics, + } + + impl $visitor_impl_generics ::serde::ser::MapVisitor for Visitor $visitor_generics { + #[inline] + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: ::serde::ser::Visitor, + { + match self.state { + $arms + _ => Ok(None), + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let size = $len - (self.state as usize); + (size, Some(size)) + } + } + + $visitor.visit_named_map($type_name, Visitor { + value: self, + state: 0, + }) + }) +} + +fn serialize_enum( + cx: &ExtCtxt, + span: Span, + builder: &aster::AstBuilder, + visitor: P, + type_ident: Ident, + variant: &ast::Variant, + fields: &[FieldInfo], + generics: &ast::Generics, +) -> P { + let type_name = builder.expr().str(type_ident); + let variant_name = builder.expr().str(variant.node.name); + + if fields.is_empty() { + quote_expr!(cx, + ::serde::ser::Visitor::visit_enum_unit( + $visitor, + $type_name, + $variant_name) + ) + } else { + serialize_variant( + cx, + span, + builder, + visitor, + type_name, + variant_name, + generics, + variant, + fields) + } +} + +fn serialize_variant( + cx: &ExtCtxt, + span: Span, + builder: &aster::AstBuilder, + visitor: P, + type_name: P, + variant_name: P, + generics: &ast::Generics, + variant: &ast::Variant, + fields: &[FieldInfo], +) -> P { + let generics = builder.from_generics(generics.clone()) + .add_lifetime_bound("'__a") + .add_ty_param_bound( + builder.path().global().ids(&["serde", "ser", "Serialize"]).build() + ) + .lifetime_name("'__a") + .build(); + + let ( + trait_name, + visitor_method_name, + tys, + ): (Ident, Ident, Vec>) = match variant.node.kind { + ast::TupleVariantKind(ref args) => { + ( + cx.ident_of("SeqVisitor"), + cx.ident_of("visit_enum_seq"), + args.iter() + .map(|arg| arg.ty.clone()) + .collect() + ) + } + + ast::StructVariantKind(ref struct_def) => { + ( + cx.ident_of("MapVisitor"), + cx.ident_of("visit_enum_map"), + struct_def.fields.iter() + .map(|field| field.node.ty.clone()) + .collect() + ) + } + }; + + let value_ty = builder.ty() + .tuple() + .with_tys(tys.into_iter().map(|ty| { + builder.ty() + .ref_() + .lifetime("'__a") + .build_ty(ty) + })) + .build(); + + let visitor_ident = builder.id("__Visitor"); + + let visitor_struct = builder.item().struct_(visitor_ident) + .generics().with(generics.clone()).build() + .field("state").usize() + .field("value").build(value_ty) + .build(); + + let visitor_expr = builder.expr().struct_path(visitor_ident) + .field("state").usize(0) + .field("value").tuple() + .with_exprs( + fields.iter().map(|field| { + builder.expr() + .addr_of() + .build(field.self_.clone()) + }) + ) + .build() + .build(); + + let mut first = true; + + let visitor_arms: Vec = fields.iter() + .enumerate() + .map(|(state, field)| { + let field_expr = builder.expr() + .tup_field(state) + .field("value").self_(); + + let visit_expr = match field.name { + Some(real_name) => { + let real_name = builder.expr().str(real_name); + + quote_expr!(cx, + ::serde::ser::Visitor::visit_map_elt( + visitor, + $first, + $real_name, + $field_expr, + ) + ) + } + None => { + quote_expr!(cx, + ::serde::ser::Visitor::visit_seq_elt( + visitor, + $first, + $field_expr, + ) + ) + } + }; + + first = false; + + quote_arm!(cx, + $state => { + self.state += 1; + Ok(Some(try!($visit_expr))) + } + ) + }) + .collect(); + + let trait_path = builder.path() + .global() + .ids(&["serde", "ser"]).id(trait_name) + .build(); + + let trait_ref = cx.trait_ref(trait_path); + let opt_trait_ref = Some(trait_ref); + + let self_ty = builder.ty() + .path() + .segment("__Visitor") + .with_generics(generics.clone()) + .build() + .build(); + + let len = fields.len(); + let impl_ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&self_ty)); + + let methods = vec![ + ast::MethodImplItem( + quote_method!(cx, + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: ::serde::ser::Visitor, + { + match self.state { + $visitor_arms + _ => Ok(None), + } + } + ) + ), + + ast::MethodImplItem( + quote_method!(cx, + fn size_hint(&self) -> (usize, Option) { + ($len - self.state as usize, Some($len - self.state as usize)) + } + ) + ), + ]; + + let visitor_impl = cx.item( + span, + impl_ident, + vec![], + ast::ItemImpl( + ast::Unsafety::Normal, + ast::ImplPolarity::Positive, + generics, + opt_trait_ref, + self_ty, + methods, + ), + ); + + quote_expr!(cx, { + $visitor_struct + $visitor_impl + + ::serde::ser::Visitor::$visitor_method_name( + $visitor, + $type_name, + $variant_name, + $visitor_expr, + ) + }) +} + +pub fn expand_derive_deserialize( + cx: &mut ExtCtxt, + sp: Span, + mitem: &MetaItem, + item: &Item, + push: &mut FnMut(P) +) { + let inline = cx.meta_word(sp, token::InternedString::new("inline")); + let attrs = vec!(cx.attribute(sp, inline)); + let trait_def = TraitDef { - span: span, + span: sp, attributes: Vec::new(), - path: Path::new_(vec!("serde", "de", "Deserialize"), None, - vec!(Box::new(Literal(Path::new_local("__D"))), - Box::new(Literal(Path::new_local("__E")))), true), + path: Path::new(vec!["serde", "de", "Deserialize"]), additional_bounds: Vec::new(), - generics: LifetimeBounds { - lifetimes: Vec::new(), - bounds: vec!(("__D", vec!(Path::new_( - vec!("serde", "de", "Deserializer"), None, - vec!(Box::new(Literal(Path::new_local("__E")))), true))), - ("__E", vec!())) - }, + generics: LifetimeBounds::empty(), + associated_types: vec![], methods: vec!( MethodDef { - name: "deserialize_token", - generics: LifetimeBounds::empty(), + name: "deserialize", + generics: LifetimeBounds { + lifetimes: Vec::new(), + bounds: vec![ + ("__D", vec![Path::new(vec!["serde", "de", "Deserializer"])]), + ], + }, explicit_self: None, - args: vec!( - Ptr( - Box::new(Literal(Path::new_local("__D"))), + args: vec![ + Ty::Ptr( + Box::new(Ty::Literal(Path::new_local("__D"))), Borrowed(None, MutMutable) ), - Literal(Path::new(vec!("serde", "de", "Token"))), - ), - ret_ty: Literal( + ], + ret_ty: Ty::Literal( Path::new_( - vec!("std", "result", "Result"), + vec!["std", "result", "Result"], None, - vec!( - Box::new(Self_), - Box::new(Literal(Path::new_local("__E"))) - ), + vec![ + Box::new(Ty::Self_), + Box::new(Ty::Literal(Path::new_(vec!["__D", "Error"], + None, + vec![], + false))), + ], true ) ), - attributes: Vec::new(), + attributes: attrs, combine_substructure: combine_substructure(Box::new(|a, b, c| { - deserialize_substructure(a, b, c) + deserialize_substructure(a, b, c, item) })), - }), - associated_types: vec!() + }) }; - trait_def.expand(cx, mitem, item, |item| push.call_mut((item,))) + trait_def.expand(cx, mitem, item, |item| push(item)) } -fn deserialize_substructure(cx: &mut ExtCtxt, - span: Span, - substr: &Substructure) -> P { - let deserializer = substr.nonself_args[0].clone(); - let token = substr.nonself_args[1].clone(); +fn deserialize_substructure( + cx: &ExtCtxt, + span: Span, + substr: &Substructure, + item: &Item, +) -> P { + let builder = aster::AstBuilder::new().span(span); - match *substr.fields { - StaticStruct(ref definition, ref fields) => { + let state = substr.nonself_args[0].clone(); + + match (&item.node, &*substr.fields) { + (&ast::ItemStruct(_, ref generics), &StaticStruct(ref struct_def, ref fields)) => { deserialize_struct( cx, span, + &builder, substr.type_ident, - &definition.fields[], + substr.type_ident, + cx.path(span, vec![substr.type_ident]), fields, - deserializer.clone(), - token) + state, + struct_def, + generics, + ) } - StaticEnum(ref definition, ref fields) => { + (&ast::ItemEnum(_, ref generics), &StaticEnum(ref enum_def, ref fields)) => { deserialize_enum( cx, - span, + &builder, substr.type_ident, - &definition.variants[], - &fields[], - deserializer, - token) + &fields, + state, + enum_def, + generics, + ) } _ => cx.bug("expected StaticEnum or StaticStruct in derive(Deserialize)") } @@ -283,227 +687,757 @@ fn deserialize_substructure(cx: &mut ExtCtxt, fn deserialize_struct( cx: &ExtCtxt, span: Span, + builder: &aster::AstBuilder, type_ident: Ident, - definitions: &[StructField], + struct_ident: Ident, + struct_path: ast::Path, fields: &StaticFields, - deserializer: P, - token: P + state: P, + struct_def: &StructDef, + generics: &ast::Generics, ) -> P { - let type_name_str = cx.expr_str(span, token::get_ident(type_ident)); + match *fields { + Unnamed(ref fields) => { + if fields.is_empty() { + deserialize_struct_empty_fields( + cx, + builder, + type_ident, + struct_ident, + struct_path, + state) + } else { + deserialize_struct_unnamed_fields( + cx, + builder, + type_ident, + struct_ident, + struct_path, + &fields, + state, + generics, + ) + } + } + Named(ref fields) => { + deserialize_struct_named_fields( + cx, + span, + builder, + type_ident, + struct_ident, + struct_path, + &fields, + state, + struct_def, + generics) + } + } +} - let fields = match *fields { - Unnamed(_) => panic!(), - Named(ref fields) => &fields[], +fn deserialize_struct_empty_fields( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + type_ident: Ident, + struct_ident: Ident, + struct_path: ast::Path, + state: P, +) -> P { + let struct_name = builder.expr().str(struct_ident); + let result = builder.expr().build_path(struct_path); + + quote_expr!(cx, { + struct __Visitor; + + impl ::serde::de::Visitor for __Visitor { + type Value = $type_ident; + + #[inline] + fn visit_unit(&mut self) -> Result<$type_ident, E> + where E: ::serde::de::Error, + { + Ok($result) + } + + #[inline] + fn visit_named_unit< + E: ::serde::de::Error, + >(&mut self, name: &str) -> Result<$type_ident, E> { + if name == $struct_name { + self.visit_unit() + } else { + Err(::serde::de::Error::syntax_error()) + } + } + + + #[inline] + fn visit_seq(&mut self, mut visitor: V) -> Result<$type_ident, V::Error> + where V: ::serde::de::SeqVisitor, + { + try!(visitor.end()); + self.visit_unit() + } + } + + $state.visit(__Visitor) + }) +} + +fn deserialize_struct_unnamed_fields( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + type_ident: Ident, + struct_ident: Ident, + struct_path: ast::Path, + fields: &[Span], + state: P, + generics: &ast::Generics, +) -> P { + let visitor_impl_generics = builder.from_generics(generics.clone()) + .add_ty_param_bound( + builder.path().global().ids(&["serde", "de", "Deserialize"]).build() + ) + .build(); + + let field_names: Vec = (0 .. fields.len()) + .map(|i| builder.id(&format!("__field{}", i))) + .collect(); + + let visit_seq_expr = declare_visit_seq( + cx, + builder, + struct_path, + &field_names, + ); + + // Build `__Visitor(PhantomData, PhantomData, ...)` + let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { + ( + builder.item().tuple_struct("__Visitor") + .build(), + builder.expr().id("__Visitor"), + ) + } else { + ( + builder.item().tuple_struct("__Visitor") + .generics().with(generics.clone()).build() + .with_tys( + generics.ty_params.iter().map(|ty_param| { + builder.ty().phantom_data().id(ty_param.ident) + }) + ) + .build(), + builder.expr().call().id("__Visitor") + .with_args( + generics.ty_params.iter().map(|_| { + builder.expr().phantom_data() + }) + ) + .build(), + ) }; - // Convert each field into a unique ident. - let field_idents: Vec = fields.iter() - .enumerate() - .map(|(idx, _)| { - cx.ident_of(&format!("field{}", idx)[]) - }) - .collect(); + let struct_name = builder.expr().str(struct_ident); - // Convert each field into their string. - let field_strs: Vec> = fields.iter() - .zip(definitions.iter()) - .map(|(&(name, _), def)| { - match find_serial_name(def.node.attrs.iter()) { - Some(serial) => cx.expr_str(span, serial), - None => cx.expr_str(span, token::get_ident(name)), + let visitor_ty = builder.ty().path() + .segment("__Visitor").with_generics(generics.clone()).build() + .build(); + + let value_ty = builder.ty().path() + .segment(type_ident).with_generics(generics.clone()).build() + .build(); + + quote_expr!(cx, { + $visitor_struct; + + impl $visitor_impl_generics ::serde::de::Visitor for $visitor_ty { + type Value = $value_ty; + + fn visit_seq<__V>(&mut self, mut visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::SeqVisitor, + { + $visit_seq_expr } - }) - .collect(); - // Declare the static vec slice of field names. - let static_fields = cx.expr_vec_slice(span, field_strs.clone()); + fn visit_named_seq<__V>(&mut self, + name: &str, + visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::SeqVisitor, + { + if name == $struct_name { + self.visit_seq(visitor) + } else { + Err(::serde::de::Error::syntax_error()) + } + } + } - // Declare each field. - let let_fields: Vec> = field_idents.iter() - .map(|ident| quote_stmt!(cx, let mut $ident = None)) - .collect(); + $state.visit($visitor_expr) + }) +} - // Declare key arms. - let idx_arms: Vec = field_idents.iter() - .enumerate() - .map(|(idx, ident)| { - quote_arm!(cx, - Some($idx) => { $ident = Some(try!($deserializer.expect_struct_value())); } - ) - }) - .collect(); - - let extract_fields: Vec> = field_idents.iter() - .zip(field_strs.iter()) - .map(|(ident, field_str)| { +fn declare_visit_seq( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + struct_path: ast::Path, + field_names: &[Ident], +) -> P { + let let_values: Vec> = field_names.iter() + .map(|name| { quote_stmt!(cx, - let $ident = match $ident { - Some($ident) => $ident, - None => try!($deserializer.missing_field($field_str)), + let $name = match try!(visitor.visit()) { + Some(value) => value, + None => { + return Err(::serde::de::Error::end_of_stream_error()); + } }; ) }) .collect(); - let result = cx.expr_struct_ident( + let result = builder.expr().call() + .build_path(struct_path) + .with_args(field_names.iter().map(|name| builder.expr().id(*name))) + .build(); + + quote_expr!(cx, { + $let_values + + try!(visitor.end()); + + Ok($result) + }) +} + +fn deserialize_struct_named_fields( + cx: &ExtCtxt, + span: Span, + builder: &aster::AstBuilder, + type_ident: Ident, + struct_ident: Ident, + struct_path: ast::Path, + fields: &[(Ident, Span)], + state: P, + struct_def: &StructDef, + generics: &ast::Generics, +) -> P { + let visitor_impl_generics = builder.from_generics(generics.clone()) + .add_ty_param_bound( + builder.path().global().ids(&["serde", "de", "Deserialize"]).build() + ) + .build(); + + // Create the field names for the fields. + let field_names: Vec = (0 .. fields.len()) + .map(|i| token::str_to_ident(&format!("__field{}", i))) + .collect(); + + // Build `__Visitor(PhantomData, PhantomData, ...)` + let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { + ( + builder.item().tuple_struct("__Visitor") + .build(), + builder.expr().id("__Visitor"), + ) + } else { + ( + builder.item().tuple_struct("__Visitor") + .generics().with(generics.clone()).build() + .with_tys( + generics.ty_params.iter().map(|ty_param| { + builder.ty().phantom_data().id(ty_param.ident) + }) + ) + .build(), + builder.expr().call().id("__Visitor") + .with_args( + generics.ty_params.iter().map(|_| { + builder.expr().phantom_data() + }) + ) + .build(), + ) + }; + + let struct_name = builder.expr().str(struct_ident); + + let visitor_ty = builder.ty().path() + .segment("__Visitor").with_generics(generics.clone()).build() + .build(); + + let value_ty = builder.ty().path() + .segment(type_ident).with_generics(generics.clone()).build() + .build(); + + let field_deserializer = declare_map_field_deserializer( + cx, span, - type_ident, - fields.iter() - .zip(field_idents.iter()) - .map(|(&(name, _), ident)| { - cx.field_imm(span, name, cx.expr_ident(span, *ident)) - }) - .collect() + builder, + &field_names, + fields, + struct_def, + ); + + let visit_map_expr = declare_visit_map( + cx, + builder, + struct_path, + &field_names, + fields, + struct_def ); quote_expr!(cx, { - try!($deserializer.expect_struct_start($token, $type_name_str)); + $field_deserializer - static FIELDS: &'static [&'static str] = $static_fields; - $let_fields + $visitor_struct; - loop { - let idx = match try!($deserializer.expect_struct_field_or_end(FIELDS)) { - Some(idx) => idx, - None => { break; } - }; + impl $visitor_impl_generics ::serde::de::Visitor for $visitor_ty { + type Value = $value_ty; - match idx { - $idx_arms - Some(_) => unreachable!(), - None => { - let _: ::serde::de::IgnoreTokens = - try!(::serde::de::Deserialize::deserialize($deserializer)); + #[inline] + fn visit_map<__V>(&mut self, mut visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::MapVisitor, + { + $visit_map_expr + } + + #[inline] + fn visit_named_map<__V>(&mut self, + name: &str, + visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::MapVisitor, + { + if name == $struct_name { + self.visit_map(visitor) + } else { + Err(::serde::de::Error::syntax_error()) } } - //try!($deserializer.ignore_field(token)) } - $extract_fields + $state.visit($visitor_expr) + }) +} + +fn field_alias(field: &ast::StructField) -> Option<&ast::Lit> { + field.node.attrs.iter() + .find(|sa| + if let MetaItem_::MetaList(ref n, _) = sa.node.value.node { + n == &"serde" + } else { + false + }) + .and_then(|sa| + if let MetaItem_::MetaList(_, ref vals) = sa.node.value.node { + vals.iter() + .fold(None, + |v, mi| + if let MetaItem_::MetaNameValue(ref n, ref lit) = mi.node { + if n == &"alias" { + Some(lit) + } else { + v + } + } else { + v + }) + } else { + None + }) +} + +fn declare_map_field_deserializer( + cx: &ExtCtxt, + span: Span, + _builder: &aster::AstBuilder, + field_names: &[ast::Ident], + fields: &[(Ident, Span)], + struct_def: &StructDef, +) -> Vec> { + // Create the field names for the fields. + let field_variants: Vec> = field_names.iter() + .map(|field| { + P(respan( + span, + ast::Variant_ { + name: *field, + attrs: Vec::new(), + kind: ast::TupleVariantKind(Vec::new()), + id: ast::DUMMY_NODE_ID, + disr_expr: None, + vis: ast::Inherited, + })) + }) + .collect(); + + let field_enum = cx.item_enum( + span, + token::str_to_ident("__Field"), + ast::EnumDef { variants: field_variants }); + + // Get aliases + let aliases : Vec> = struct_def.fields.iter() + .map(field_alias) + .collect(); + + // Match arms to extract a field from a string + let field_arms: Vec = fields.iter() + .zip(field_names.iter()) + .zip(aliases.iter()) + .map(|((&(name, span), field), alias_lit)| { + let s = match alias_lit { + &None => cx.expr_str(span, token::get_ident(name)) , + &Some(lit) =>{ + let lit = (*lit).clone(); + cx.expr_lit(lit.span, lit.node) + }, + }; + quote_arm!(cx, $s => Ok(__Field::$field),)}) + .collect(); + + vec![ + quote_item!(cx, + #[allow(non_camel_case_types)] + $field_enum + ).unwrap(), + + quote_item!(cx, + struct __FieldVisitor; + ).unwrap(), + + quote_item!(cx, + impl ::serde::de::Visitor for __FieldVisitor { + type Value = __Field; + + fn visit_str(&mut self, value: &str) -> Result<__Field, E> + where E: ::serde::de::Error, + { + match value { + $field_arms + _ => Err(::serde::de::Error::syntax_error()), + } + } + } + ).unwrap(), + + quote_item!(cx, + impl ::serde::de::Deserialize for __Field { + #[inline] + fn deserialize(state: &mut S) -> Result<__Field, S::Error> + where S: ::serde::de::Deserializer, + { + state.visit(__FieldVisitor) + } + } + ).unwrap(), + ] +} + + +fn default_value(field: &ast::StructField) -> bool { + field.node.attrs.iter() + .any(|sa| + if let MetaItem_::MetaList(ref n, ref vals) = sa.node.value.node { + if n == &"serde" { + vals.iter() + .map(|mi| + if let MetaItem_::MetaWord(ref n) = mi.node { + n == &"default" + } else { + false + }) + .any(|x| x) + } else { + false + } + } + else { + false + }) +} + +fn declare_visit_map( + cx: &ExtCtxt, + builder: &aster::AstBuilder, + struct_path: ast::Path, + field_names: &[Ident], + fields: &[(Ident, Span)], + struct_def: &StructDef, +) -> P { + + // Declare each field. + let let_values: Vec> = field_names.iter() + .zip(struct_def.fields.iter()) + .map(|(field, sf)| { + if default_value(sf) { + quote_stmt!( + cx, + let mut $field = Some(::std::default::Default::default());) + } else { + quote_stmt!(cx, let mut $field = None;) + } + }) + .collect(); + + // Match arms to extract a value for a field. + let value_arms: Vec = field_names.iter() + .map(|field| { + quote_arm!(cx, __Field::$field => { + $field = Some(try!(visitor.visit_value())); + }) + }) + .collect(); + + let extract_values: Vec> = fields.iter() + .zip(field_names.iter()) + .map(|(&(name, span), field)| { + let name_str = cx.expr_str(span, token::get_ident(name)); + quote_stmt!(cx, + let $field = match $field { + Some($field) => $field, + None => { + return Err(::serde::de::Error::missing_field_error($name_str)); + } + }; + ) + }) + .collect(); + + let result = builder.expr().struct_path(struct_path) + .with_id_exprs( + fields.iter() + .zip(field_names.iter()) + .map(|(&(name, _), field)| { + (name, builder.expr().id(field)) + }) + ) + .build(); + + quote_expr!(cx, { + $let_values + + while let Some(key) = try!(visitor.visit_key()) { + match key { + $value_arms + } + } + + $extract_values Ok($result) }) } fn deserialize_enum( cx: &ExtCtxt, - span: Span, + builder: &aster::AstBuilder, type_ident: Ident, - definitions: &[P], fields: &[(Ident, Span, StaticFields)], - deserializer: P, - token: P + state: P, + enum_def: &EnumDef, + generics: &ast::Generics, ) -> P { - let type_name = cx.expr_str(span, token::get_ident(type_ident)); + let visitor_impl_generics = builder.from_generics(generics.clone()) + .add_ty_param_bound( + builder.path().global().ids(&["serde", "de", "Deserialize"]).build() + ) + .build(); - let serial_names = definitions.iter().map(|def| - find_serial_name(def.node.attrs.iter()) - ).collect::>>(); + // Build `__Visitor(PhantomData, PhantomData, ...)` + let (visitor_struct, visitor_expr) = if generics.ty_params.is_empty() { + ( + builder.item().tuple_struct("__Visitor") + .build(), + builder.expr().id("__Visitor"), + ) + } else { + ( + builder.item().tuple_struct("__Visitor") + .generics().with(generics.clone()).build() + .with_tys( + generics.ty_params.iter().map(|ty_param| { + builder.ty().phantom_data().id(ty_param.ident) + }) + ) + .build(), + builder.expr().call().id("__Visitor") + .with_args( + generics.ty_params.iter().map(|_| { + builder.expr().phantom_data() + }) + ) + .build(), + ) + }; - let variants = fields.iter() - .map(|&(name, span, _)| { - cx.expr_str(span, token::get_ident(name)) - }) - .collect(); + let visitor_ty = builder.ty().path() + .segment("__Visitor").with_generics(generics.clone()).build() + .build(); - let variants = cx.expr_vec(span, variants); + let value_ty = builder.ty().path() + .segment(type_ident).with_generics(generics.clone()).build() + .build(); - let arms: Vec = fields.iter() - .enumerate() - .map(|(i, &(name, span, ref parts))| { - let path = cx.path(span, vec![type_ident, name]); - let call = deserialize_static_fields( + let type_name = builder.expr().str(type_ident); + + // Match arms to extract a variant from a string + let variant_arms: Vec = fields.iter() + .zip(enum_def.variants.iter()) + .map(|(&(name, span, ref fields), variant_ptr)| { + let value = deserialize_enum_variant( cx, span, - path, - &serial_names[], - parts, - |&: cx, _, _| { - quote_expr!(cx, try!($deserializer.expect_enum_elt())) - } + builder, + type_ident, + name, + fields, + cx.expr_ident(span, cx.ident_of("visitor")), + variant_ptr, + &visitor_impl_generics, + &visitor_ty, + &visitor_expr, + &value_ty, ); - quote_arm!(cx, $i => $call,) + let s = builder.expr().str(name); + quote_arm!(cx, $s => $value,) }) .collect(); quote_expr!(cx, { - let i = try!($deserializer.expect_enum_start($token, $type_name, &$variants)); + $visitor_struct; - let result = match i { - $arms - _ => { unreachable!() } - }; + impl $visitor_impl_generics ::serde::de::Visitor for $visitor_ty { + type Value = $value_ty; - try!($deserializer.expect_enum_end()); + fn visit_enum<__V>(&mut self, + name: &str, + variant: &str, + visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::EnumVisitor, + { + if name == $type_name { + self.visit_variant(variant, visitor) + } else { + Err(::serde::de::Error::syntax_error()) + } + } - Ok(result) + fn visit_variant<__V>(&mut self, + name: &str, + mut visitor: __V) -> Result<$value_ty, __V::Error> + where __V: ::serde::de::EnumVisitor + { + match name { + $variant_arms + _ => Err(::serde::de::Error::syntax_error()), + } + } + } + + $state.visit_enum($visitor_expr) }) } -/// Create a deserializer for a single enum variant/struct: -/// - `outer_pat_ident` is the name of this enum variant/struct -/// - `getarg` should retrieve the `uint`-th field with name `&str`. -fn deserialize_static_fields( +fn deserialize_enum_variant( cx: &ExtCtxt, span: Span, - outer_pat_path: ast::Path, - serial_names: &[Option], + builder: &aster::AstBuilder, + type_ident: Ident, + variant_ident: Ident, fields: &StaticFields, - getarg: F -) -> P where F: Fn(&ExtCtxt, Span, token::InternedString) -> P { + state: P, + variant_ptr: &P, + visitor_impl_generics: &ast::Generics, + visitor_ty: &P, + visitor_expr: &P, + value_ty: &P, +) -> P { + let variant_path = cx.path(span, vec![type_ident, variant_ident]); + match *fields { Unnamed(ref fields) => { - let path_expr = cx.expr_path(outer_pat_path); if fields.is_empty() { - path_expr - } else { - let fields = fields.iter().enumerate().map(|(i, &span)| { - getarg( - cx, - span, - token::intern_and_get_ident(&format!("_field{}", i)[]) - ) - }).collect(); + let result = cx.expr_path(variant_path); - cx.expr_call(span, path_expr, fields) + quote_expr!(cx, { + try!($state.visit_unit()); + Ok($result) + }) + } else { + // Create the field names for the fields. + let field_names: Vec = (0 .. fields.len()) + .map(|i| token::str_to_ident(&format!("__field{}", i))) + .collect(); + + let visit_seq_expr = declare_visit_seq( + cx, + builder, + variant_path, + &field_names, + ); + + quote_expr!(cx, { + impl $visitor_impl_generics ::serde::de::EnumSeqVisitor for $visitor_ty { + type Value = $value_ty; + + fn visit< + V: ::serde::de::SeqVisitor, + >(&mut self, mut visitor: V) -> Result<$value_ty, V::Error> { + $visit_seq_expr + } + } + + $state.visit_seq($visitor_expr) + }) } } Named(ref fields) => { - // use the field's span to get nicer error messages. - let fields = serial_names.iter() - .zip(fields.iter()).map(|(serial_name, &(name, span))| { - let effective_name = serial_name.clone().unwrap_or( - token::get_ident(name) - ); - let arg = getarg( - cx, - span, - effective_name - ); - cx.field_imm(span, name, arg) - }).collect(); + // Create the field names for the fields. + let field_names: Vec = (0 .. fields.len()) + .map(|i| token::str_to_ident(&format!("__field{}", i))) + .collect(); - cx.expr_struct(span, outer_pat_path, fields) - } - } -} + let field_deserializer = declare_map_field_deserializer( + cx, + span, + builder, + &field_names, + fields, + match variant_ptr.node.kind { + ast::VariantKind::StructVariantKind(ref sd) => &*sd, + _ => panic!("Mismatched enum types") + }, + ); -fn find_serial_name<'a, I>(iterator: I) -> Option where - I: Iterator -{ - for at in iterator { - match at.node.value.node { - MetaNameValue(ref at_name, ref value) => { - match (&at_name[], &value.node) { - ("serial_name", &LitStr(ref string, _)) => { - attr::mark_used(at); - return Some(string.clone()); - }, - _ => () + let visit_map_expr = declare_visit_map( + cx, + builder, + variant_path, + &field_names, + fields, + match variant_ptr.node.kind { + ast::VariantKind::StructVariantKind(ref sd) => &*sd, + _ => panic!("Mismatched enum types") + }, + ); + + quote_expr!(cx, { + $field_deserializer + + impl $visitor_impl_generics ::serde::de::EnumMapVisitor for $visitor_ty { + type Value = $value_ty; + + fn visit< + V: ::serde::de::MapVisitor, + >(&mut self, mut visitor: V) -> Result<$value_ty, V::Error> { + $visit_map_expr + } } - }, - _ => () + + $state.visit_map($visitor_expr) + }) } } - None } diff --git a/src/de.rs b/src/de.rs index 6a5668b9..2bf7328d 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,1072 +1,819 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet}; -use std::collections::hash_map::Hasher; +use std::collections::{HashMap, BTreeMap}; use std::hash::Hash; -use std::iter::FromIterator; -use std::num::{self, FromPrimitive}; -use std::option; -use std::rc::Rc; -use std::string; -use std::sync::Arc; +use std::marker::PhantomData; +use std::num::FromPrimitive; +use std::path; +use std::str; -#[derive(Clone, PartialEq, Debug)] -pub enum Token { - Null, - Bool(bool), - Isize(isize), - I8(i8), - I16(i16), - I32(i32), - I64(i64), - Usize(usize), - U8(u8), - U16(u16), - U32(u32), - U64(u64), - F32(f32), - F64(f64), - Char(char), - Str(&'static str), - String(String), - Option(bool), +/////////////////////////////////////////////////////////////////////////////// - TupleStart(usize), - StructStart(&'static str, usize), - EnumStart(&'static str, &'static str, usize), - SeqStart(usize), - MapStart(usize), +pub trait Error { + fn syntax_error() -> Self; - End, + fn end_of_stream_error() -> Self; + + fn missing_field_error(&'static str) -> Self; } -impl Token { - pub fn to_kind(&self) -> TokenKind { - match *self { - Token::Null => TokenKind::NullKind, - Token::Bool(_) => TokenKind::BoolKind, - Token::Isize(_) => TokenKind::IsizeKind, - Token::I8(_) => TokenKind::I8Kind, - Token::I16(_) => TokenKind::I16Kind, - Token::I32(_) => TokenKind::I32Kind, - Token::I64(_) => TokenKind::I64Kind, - Token::Usize(_) => TokenKind::UsizeKind, - Token::U8(_) => TokenKind::U8Kind, - Token::U16(_) => TokenKind::U16Kind, - Token::U32(_) => TokenKind::U32Kind, - Token::U64(_) => TokenKind::U64Kind, - Token::F32(_) => TokenKind::F32Kind, - Token::F64(_) => TokenKind::F64Kind, - Token::Char(_) => TokenKind::CharKind, - Token::Str(_) => TokenKind::StrKind, - Token::String(_) => TokenKind::StringKind, - Token::Option(_) => TokenKind::OptionKind, - Token::TupleStart(_) => TokenKind::TupleStartKind, - Token::StructStart(_, _) => TokenKind::StructStartKind, - Token::EnumStart(_, _, _) => TokenKind::EnumStartKind, - Token::SeqStart(_) => TokenKind::SeqStartKind, - Token::MapStart(_) => TokenKind::MapStartKind, - Token::End => TokenKind::EndKind, - } +pub trait Deserialize { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer; +} + +pub trait Deserializer { + type Error: Error; + + fn visit(&mut self, visitor: V) -> Result + where V: Visitor; + + /// The `visit_option` method allows a `Deserialize` type to inform the + /// `Deserializer` that it's expecting an optional value. This allows + /// deserializers that encode an optional value as a nullable value to + /// convert the null value into a `None`, and a regular value as + /// `Some(value)`. + #[inline] + fn visit_option(&mut self, visitor: V) -> Result + where V: Visitor, + { + self.visit(visitor) + } + + /// The `visit_enum` method allows a `Deserialize` type to inform the + /// `Deserializer` that it's expecting an enum value. This allows + /// deserializers that provide a custom enumeration serialization to + /// properly deserialize the type. + #[inline] + fn visit_enum(&mut self, visitor: V) -> Result + where V: Visitor, + { + self.visit(visitor) } } -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum TokenKind { - NullKind, - BoolKind, - IsizeKind, - I8Kind, - I16Kind, - I32Kind, - I64Kind, - UsizeKind, - U8Kind, - U16Kind, - U32Kind, - U64Kind, - F32Kind, - F64Kind, - CharKind, - StrKind, - StringKind, - OptionKind, +pub trait Visitor { + type Value; - TupleStartKind, - StructStartKind, - EnumStartKind, - SeqStartKind, - MapStartKind, + fn visit_bool(&mut self, _v: bool) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } - EndKind, -} + fn visit_isize(&mut self, v: isize) -> Result + where E: Error, + { + self.visit_i64(v as i64) + } -static PRIMITIVE_TOKEN_KINDS: &'static [TokenKind] = &[ - TokenKind::IsizeKind, - TokenKind::I8Kind, - TokenKind::I16Kind, - TokenKind::I32Kind, - TokenKind::I64Kind, - TokenKind::UsizeKind, - TokenKind::U8Kind, - TokenKind::U16Kind, - TokenKind::U32Kind, - TokenKind::U64Kind, - TokenKind::F32Kind, - TokenKind::F64Kind, -]; + fn visit_i8(&mut self, v: i8) -> Result + where E: Error, + { + self.visit_i64(v as i64) + } -static STR_TOKEN_KINDS: &'static [TokenKind] = &[ - TokenKind::StrKind, - TokenKind::StringKind, -]; + fn visit_i16(&mut self, v: i16) -> Result + where E: Error, + { + self.visit_i64(v as i64) + } -static COMPOUND_TOKEN_KINDS: &'static [TokenKind] = &[ - TokenKind::OptionKind, - TokenKind::EnumStartKind, - TokenKind::StructStartKind, - TokenKind::TupleStartKind, - TokenKind::SeqStartKind, - TokenKind::MapStartKind, -]; + fn visit_i32(&mut self, v: i32) -> Result + where E: Error, + { + self.visit_i64(v as i64) + } -impl ::std::fmt::Debug for TokenKind { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - match *self { - TokenKind::NullKind => "Null".fmt(f), - TokenKind::BoolKind => "Bool".fmt(f), - TokenKind::IsizeKind => "Isize".fmt(f), - TokenKind::I8Kind => "I8".fmt(f), - TokenKind::I16Kind => "I16".fmt(f), - TokenKind::I32Kind => "I32".fmt(f), - TokenKind::I64Kind => "I64".fmt(f), - TokenKind::UsizeKind => "Usize".fmt(f), - TokenKind::U8Kind => "U8".fmt(f), - TokenKind::U16Kind => "U16".fmt(f), - TokenKind::U32Kind => "U32".fmt(f), - TokenKind::U64Kind => "U64".fmt(f), - TokenKind::F32Kind => "F32".fmt(f), - TokenKind::F64Kind => "F64".fmt(f), - TokenKind::CharKind => "Char".fmt(f), - TokenKind::StrKind => "Str".fmt(f), - TokenKind::StringKind => "String".fmt(f), - TokenKind::OptionKind => "Option".fmt(f), - TokenKind::TupleStartKind => "TupleStart".fmt(f), - TokenKind::StructStartKind => "StructStart".fmt(f), - TokenKind::EnumStartKind => "EnumStart".fmt(f), - TokenKind::SeqStartKind => "SeqStart".fmt(f), - TokenKind::MapStartKind => "MapStart".fmt(f), - TokenKind::EndKind => "Token::End".fmt(f), - } + fn visit_i64(&mut self, _v: i64) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + fn visit_usize(&mut self, v: usize) -> Result + where E: Error, + { + self.visit_u64(v as u64) + } + + fn visit_u8(&mut self, v: u8) -> Result + where E: Error, + { + self.visit_u64(v as u64) + } + + fn visit_u16(&mut self, v: u16) -> Result + where E: Error, + { + self.visit_u64(v as u64) + } + + fn visit_u32(&mut self, v: u32) -> Result + where E: Error, + { + self.visit_u64(v as u64) + } + + fn visit_u64(&mut self, _v: u64) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + fn visit_f32(&mut self, v: f32) -> Result + where E: Error, + { + self.visit_f64(v as f64) + } + + fn visit_f64(&mut self, _v: f64) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_char(&mut self, v: char) -> Result + where E: 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()) + } + + fn visit_str(&mut self, _v: &str) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_string(&mut self, v: String) -> Result + where E: Error, + { + self.visit_str(&v) + } + + fn visit_unit(&mut self) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_named_unit(&mut self, _name: &str) -> Result + where E: Error, + { + self.visit_unit() + } + + fn visit_none(&mut self) -> Result + where E: Error, + { + Err(Error::syntax_error()) + } + + fn visit_some(&mut self, _deserializer: &mut D) -> Result + where D: Deserializer, + { + Err(Error::syntax_error()) + } + + fn visit_seq(&mut self, _visitor: V) -> Result + where V: SeqVisitor, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_named_seq(&mut self, _name: &str, visitor: V) -> Result + where V: SeqVisitor, + { + self.visit_seq(visitor) + } + + fn visit_map(&mut self, _visitor: V) -> Result + where V: MapVisitor, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_named_map(&mut self, _name: &str, visitor: V) -> Result + where V: MapVisitor, + { + self.visit_map(visitor) + } + + #[inline] + fn visit_enum(&mut self, + _name: &str, + _variant: &str, + _visitor: V) -> Result + where V: EnumVisitor, + { + Err(Error::syntax_error()) + } + + #[inline] + fn visit_variant(&mut self, _name: &str, _visitor: V) -> Result + where V: EnumVisitor, + { + Err(Error::syntax_error()) } } -macro_rules! to_result { - ($expr:expr, $err:expr) => { - match $expr { - Some(value) => Ok(value), - None => Err($err), - } +/////////////////////////////////////////////////////////////////////////////// + +pub trait SeqVisitor { + type Error: Error; + + fn visit(&mut self) -> Result, Self::Error> + where T: Deserialize; + + fn end(&mut self) -> Result<(), Self::Error>; + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, None) } } -pub trait Deserializer: Iterator> + Sized { - /// Called when a `Deserialize` expected more tokens, but the - /// `Deserializer` was empty. - fn end_of_stream_error(&mut self) -> E; - - /// Called when a `Deserializer` was unable to properly parse the stream. - fn syntax_error(&mut self, token: Token, expected: &'static [TokenKind]) -> E; - - /// Called when a named structure or enum got a name that it didn't expect. - fn unexpected_name_error(&mut self, token: Token) -> E; - - /// Called when a value was unable to be coerced into another value. - fn conversion_error(&mut self, token: Token) -> E; - - /// Called when a `Deserialize` structure did not deserialize a field - /// named `field`. - fn missing_field< - T: Deserialize - >(&mut self, field: &'static str) -> Result; - - /* - /// Called when a `Deserialize` has decided to not consume this token. - fn ignore_field(&mut self, _token: Token) -> Result<(), E> { - let _: IgnoreTokens = try!(Deserialize::deserialize(self)); - Ok(()) - } - */ +impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor { + type Error = V::Error; #[inline] - fn expect_token(&mut self) -> Result { - self.next().unwrap_or_else(|| Err(self.end_of_stream_error())) + fn visit(&mut self) -> Result, V::Error> + where T: Deserialize + { + (**self).visit() } #[inline] - fn expect_null(&mut self, token: Token) -> Result<(), E> { - match token { - Token::Null => Ok(()), - Token::TupleStart(_) | Token::SeqStart(_) => { - match try!(self.expect_token()) { - Token::End => Ok(()), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::NullKind, - TokenKind::TupleStartKind, - TokenKind::SeqStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } + fn end(&mut self) -> Result<(), V::Error> { + (**self).end() } #[inline] - fn expect_bool(&mut self, token: Token) -> Result { - match token { - Token::Bool(value) => Ok(value), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::BoolKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() } +} + +/////////////////////////////////////////////////////////////////////////////// + +pub trait MapVisitor { + type Error: Error; #[inline] - fn expect_num(&mut self, token: Token) -> Result { - match token { - Token::Isize(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::I8(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::I16(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::I32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::I64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::Usize(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::U8(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::U16(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::U32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::U64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::F32(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - Token::F64(x) => to_result!(num::cast(x), self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - token => Err(self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - } - } - - #[inline] - fn expect_from_primitive(&mut self, token: Token) -> Result { - match token { - Token::Isize(x) => to_result!(num::from_int(x), self.conversion_error(token)), - Token::I8(x) => to_result!(num::from_i8(x), self.conversion_error(token)), - Token::I16(x) => to_result!(num::from_i16(x), self.conversion_error(token)), - Token::I32(x) => to_result!(num::from_i32(x), self.conversion_error(token)), - Token::I64(x) => to_result!(num::from_i64(x), self.conversion_error(token)), - Token::Usize(x) => to_result!(num::from_uint(x), self.conversion_error(token)), - Token::U8(x) => to_result!(num::from_u8(x), self.conversion_error(token)), - Token::U16(x) => to_result!(num::from_u16(x), self.conversion_error(token)), - Token::U32(x) => to_result!(num::from_u32(x), self.conversion_error(token)), - Token::U64(x) => to_result!(num::from_u64(x), self.conversion_error(token)), - Token::F32(x) => to_result!(num::from_f32(x), self.conversion_error(token)), - Token::F64(x) => to_result!(num::from_f64(x), self.conversion_error(token)), - token => Err(self.syntax_error(token, PRIMITIVE_TOKEN_KINDS)), - } - } - - #[inline] - fn expect_char(&mut self, token: Token) -> Result { - match token { - Token::Char(value) => Ok(value), - Token::Str(value) if value.chars().count() == 1 => { - Ok(value.char_at(0)) - } - Token::String(ref value) if value[].chars().count() == 1 => { - Ok(value[].char_at(0)) - } - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::CharKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_str(&mut self, token: Token) -> Result<&'static str, E> { - match token { - Token::Str(value) => Ok(value), - token => Err(self.syntax_error(token, STR_TOKEN_KINDS)), - } - } - - #[inline] - fn expect_string(&mut self, token: Token) -> Result { - match token { - Token::Char(value) => Ok(value.to_string()), - Token::Str(value) => Ok(value.to_string()), - Token::String(value) => Ok(value), - token => Err(self.syntax_error(token, STR_TOKEN_KINDS)), - } - } - - #[inline] - fn expect_option< - T: Deserialize - >(&mut self, token: Token) -> Result, E> { - match token { - Token::Option(false) => Ok(None), - Token::Option(true) => { - let value: T = try!(Deserialize::deserialize(self)); - Ok(Some(value)) - } - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::OptionKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_tuple_start(&mut self, token: Token) -> Result { - match token { - Token::TupleStart(len) => Ok(len), - Token::SeqStart(len) => Ok(len), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::TupleStartKind, - TokenKind::SeqStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_tuple_elt< - T: Deserialize - >(&mut self) -> Result { - Deserialize::deserialize(self) - } - - #[inline] - fn expect_tuple_end(&mut self) -> Result<(), E> { - match try!(self.expect_token()) { - Token::End => Ok(()), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_struct_start(&mut self, token: Token, name: &str) -> Result<(), E> { - match token { - Token::StructStart(n, _) => { - if name == n { - Ok(()) - } else { - Err(self.unexpected_name_error(token)) - } - } - _ => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::StructStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_struct_field_or_end(&mut self, - fields: &'static [&'static str] - ) -> Result>, E> { - match try!(self.expect_token()) { - Token::End => { - Ok(None) - } - Token::Str(n) => { - Ok(Some(fields.iter().position(|field| *field == n))) - } - Token::String(n) => { - Ok(Some(fields.iter().position(|field| *field == &n[]))) - } - token => { - Err(self.syntax_error(token, STR_TOKEN_KINDS)) - } - } - } - - #[inline] - fn expect_struct_value< - T: Deserialize - >(&mut self) -> Result { - Deserialize::deserialize(self) - } - - #[inline] - fn expect_struct_end(&mut self) -> Result<(), E> { - match try!(self.expect_token()) { - Token::End => Ok(()), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_enum_start(&mut self, token: Token, name: &str, variants: &[&str]) -> Result { - match token { - Token::EnumStart(n, v, _) => { - if name == n { - match variants.iter().position(|variant| *variant == v) { - Some(position) => Ok(position), - None => Err(self.unexpected_name_error(token)), - } - } else { - Err(self.unexpected_name_error(token)) - } - } - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EnumStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_enum_elt< - T: Deserialize - >(&mut self) -> Result { - Deserialize::deserialize(self) - } - - #[inline] - fn expect_enum_end(&mut self) -> Result<(), E> { - match try!(self.expect_token()) { - Token::End => Ok(()), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_seq_start(&mut self, token: Token) -> Result { - match token { - Token::TupleStart(len) => Ok(len), - Token::SeqStart(len) => Ok(len), - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::TupleStartKind, - TokenKind::SeqStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_seq_elt_or_end< - T: Deserialize - >(&mut self) -> Result, E> { - match try!(self.expect_token()) { - Token::End => Ok(None), - token => { - let value = try!(Deserialize::deserialize_token(self, token)); - Ok(Some(value)) - } - } - } - - #[inline] - fn expect_seq< - T: Deserialize, - C: FromIterator - >(&mut self, token: Token) -> Result { - let len = try!(self.expect_seq_start(token)); - let mut err = None; - - let collection: C = { - let d = SeqDeserializer { - d: self, - len: len, - err: &mut err, - }; - - d.collect() - }; - - match err { - Some(err) => Err(err), - None => Ok(collection), - } - } - - #[inline] - fn expect_map_start(&mut self, token: Token) -> Result { - match token { - Token::MapStart(len) => Ok(len), - _ => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::MapStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) - } - } - } - - #[inline] - fn expect_map_elt_or_end< - K: Deserialize, - V: Deserialize - >(&mut self) -> Result, E> { - match try!(self.expect_token()) { - Token::End => Ok(None), - token => { - let key = try!(Deserialize::deserialize_token(self, token)); - let value = try!(Deserialize::deserialize(self)); + fn visit(&mut self) -> Result, Self::Error> + where K: Deserialize, + V: Deserialize, + { + match try!(self.visit_key()) { + Some(key) => { + let value = try!(self.visit_value()); Ok(Some((key, value))) } + None => Ok(None) } } + fn visit_key(&mut self) -> Result, Self::Error> + where K: Deserialize; + + fn visit_value(&mut self) -> Result + where V: Deserialize; + + fn end(&mut self) -> Result<(), Self::Error>; + #[inline] - fn expect_map< - K: Deserialize, - V: Deserialize, - C: FromIterator<(K, V)> - >(&mut self, token: Token) -> Result { - let len = try!(self.expect_map_start(token)); - let mut err = None; + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} - let collection: C = { - let d = MapDeserializer { - d: self, - len: len, - err: &mut err, - }; +impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor { + type Error = V_::Error; - d.collect() - }; + #[inline] + fn visit(&mut self) -> Result, V_::Error> + where K: Deserialize, + V: Deserialize, + { + (**self).visit() + } - match err { - Some(err) => Err(err), - None => Ok(collection), + #[inline] + fn visit_key(&mut self) -> Result, V_::Error> + where K: Deserialize + { + (**self).visit_key() + } + + #[inline] + fn visit_value(&mut self) -> Result + where V: Deserialize + { + (**self).visit_value() + } + + #[inline] + fn end(&mut self) -> Result<(), V_::Error> { + (**self).end() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + +pub trait EnumVisitor { + type Error: Error; + + fn visit_unit(&mut self) -> Result<(), Self::Error> { + Err(Error::syntax_error()) + } + + fn visit_seq(&mut self, _visitor: V) -> Result + where V: EnumSeqVisitor, + { + Err(Error::syntax_error()) + } + + fn visit_map(&mut self, _visitor: V) -> Result + where V: EnumMapVisitor, + { + Err(Error::syntax_error()) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +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; +} + +/////////////////////////////////////////////////////////////////////////////// + +struct UnitVisitor; + +impl Visitor for UnitVisitor { + type Value = (); + + fn visit_unit(&mut self) -> Result<(), E> + where E: Error, + { + Ok(()) + } + + fn visit_seq(&mut self, mut visitor: V) -> Result<(), V::Error> + where V: SeqVisitor, + { + visitor.end() + } +} + +impl Deserialize for () { + fn deserialize(deserializer: &mut D) -> Result<(), D::Error> + where D: Deserializer, + { + deserializer.visit(UnitVisitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +struct BoolVisitor; + +impl Visitor for BoolVisitor { + type Value = bool; + + fn visit_bool(&mut self, v: bool) -> Result + where E: Error, + { + Ok(v) + } +} + +impl Deserialize for bool { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer, + { + deserializer.visit(BoolVisitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +macro_rules! impl_deserialize_num_method { + ($src_ty:ty, $method:ident, $from_method:ident) => { + #[inline] + fn $method(&mut self, v: $src_ty) -> Result + where E: Error, + { + match FromPrimitive::$from_method(v) { + Some(v) => Ok(v), + None => Err(Error::syntax_error()), + } } } } -////////////////////////////////////////////////////////////////////////////// +pub struct PrimitiveVisitor { + marker: PhantomData, +} -struct SeqDeserializer<'a, D: 'a, E: 'a, T> { - d: &'a mut D, - len: usize, - err: &'a mut Option, +impl PrimitiveVisitor { + #[inline] + pub fn new() -> Self { + PrimitiveVisitor { + marker: PhantomData, + } + } } impl< - 'a, - D: Deserializer, - E, - T: Deserialize -> Iterator for SeqDeserializer<'a, D, E, T> { - type Item = T; + T: Deserialize + FromPrimitive +> self::Visitor for PrimitiveVisitor { + type Value = T; - #[inline] - fn next(&mut self) -> option::Option { - match self.d.expect_seq_elt_or_end() { - Ok(next) => { - self.len -= 1; - next - } - Err(err) => { - *self.err = Some(err); - None - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, option::Option) { - (self.len, Some(self.len)) - } + impl_deserialize_num_method!(isize, visit_isize, from_isize); + impl_deserialize_num_method!(i8, visit_i8, from_i8); + impl_deserialize_num_method!(i16, visit_i16, from_i16); + impl_deserialize_num_method!(i32, visit_i32, from_i32); + impl_deserialize_num_method!(i64, visit_i64, from_i64); + impl_deserialize_num_method!(usize, visit_usize, from_usize); + impl_deserialize_num_method!(u8, visit_u8, from_u8); + impl_deserialize_num_method!(u16, visit_u16, from_u16); + impl_deserialize_num_method!(u32, visit_u32, from_u32); + impl_deserialize_num_method!(u64, visit_u64, from_u64); + impl_deserialize_num_method!(f32, visit_f32, from_f32); + impl_deserialize_num_method!(f64, visit_f64, from_f64); } -////////////////////////////////////////////////////////////////////////////// - -struct MapDeserializer<'a, D:'a, E: 'a, K, V> { - d: &'a mut D, - len: usize, - err: &'a mut option::Option, -} - -impl< - 'a, - D: Deserializer, - E, - K: Deserialize, - V: Deserialize -> Iterator for MapDeserializer<'a, D, E, K, V> { - type Item = (K, V); - - #[inline] - fn next(&mut self) -> option::Option<(K, V)> { - match self.d.expect_map_elt_or_end() { - Ok(next) => next, - Err(err) => { - *self.err = Some(err); - None - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, option::Option) { - (self.len, Some(self.len)) - } -} - -////////////////////////////////////////////////////////////////////////////// - -pub trait Deserialize, E>: Sized { - #[inline] - fn deserialize(d: &mut D) -> Result { - let token = try!(d.expect_token()); - Deserialize::deserialize_token(d, token) - } - - fn deserialize_token(d: &mut D, token: Token) -> Result; -} - -////////////////////////////////////////////////////////////////////////////// - -macro_rules! impl_deserialize { - ($ty:ty, $method:ident) => { - impl, E> Deserialize for $ty { +macro_rules! impl_deserialize_num { + ($ty:ty) => { + impl Deserialize for $ty { #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result<$ty, E> { - d.$method(token) + fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> + where D: Deserializer, + { + deserializer.visit(PrimitiveVisitor::new()) } } } } -impl_deserialize!(bool, expect_bool); -impl_deserialize!(isize, expect_num); -impl_deserialize!(i8, expect_num); -impl_deserialize!(i16, expect_num); -impl_deserialize!(i32, expect_num); -impl_deserialize!(i64, expect_num); -impl_deserialize!(usize, expect_num); -impl_deserialize!(u8, expect_num); -impl_deserialize!(u16, expect_num); -impl_deserialize!(u32, expect_num); -impl_deserialize!(u64, expect_num); -impl_deserialize!(f32, expect_num); -impl_deserialize!(f64, expect_num); -impl_deserialize!(char, expect_char); -impl_deserialize!(&'static str, expect_str); -impl_deserialize!(string::String, expect_string); +impl_deserialize_num!(isize); +impl_deserialize_num!(i8); +impl_deserialize_num!(i16); +impl_deserialize_num!(i32); +impl_deserialize_num!(i64); +impl_deserialize_num!(usize); +impl_deserialize_num!(u8); +impl_deserialize_num!(u16); +impl_deserialize_num!(u32); +impl_deserialize_num!(u64); +impl_deserialize_num!(f32); +impl_deserialize_num!(f64); -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +struct CharVisitor; + +impl Visitor for CharVisitor { + type Value = char; -impl< - D: Deserializer, - E, - T: Deserialize -> Deserialize for Box { #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - Ok(Box::new(try!(Deserialize::deserialize_token(d, token)))) + fn visit_char(&mut self, v: char) -> Result + where E: Error, + { + Ok(v) } -} -impl< - D: Deserializer, - E, - T: Deserialize -> Deserialize for Rc { #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - Ok(Rc::new(try!(Deserialize::deserialize_token(d, token)))) - } -} - -impl< - D: Deserializer, - E, - T: Deserialize + Send + Sync -> Deserialize for Arc { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - Ok(Arc::new(try!(Deserialize::deserialize_token(d, token)))) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - D: Deserializer, - E, - T: Deserialize -> Deserialize for option::Option { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_option(token) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - D: Deserializer, - E, - T: Deserialize -> Deserialize for Vec { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_seq(token) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - D: Deserializer, - E, - K: Deserialize + Eq + Hash, - V: Deserialize -> Deserialize for HashMap { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_map(token) - } -} - -impl< - D: Deserializer, - E, - K: Deserialize + Ord, - V: Deserialize -> Deserialize for BTreeMap { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_map(token) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - D: Deserializer, - E, - T: Deserialize + Eq + Hash -> Deserialize for HashSet { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_seq(token) - } -} - -impl< - D: Deserializer, - E, - T: Deserialize + Ord -> Deserialize for BTreeSet { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result, E> { - d.expect_seq(token) - } -} - -////////////////////////////////////////////////////////////////////////////// - -macro_rules! peel { - ($name:ident, $($other:ident,)*) => ( impl_deserialize_tuple!($($other,)*); ) -} - -macro_rules! impl_deserialize_tuple { - () => { - impl< - D: Deserializer, - E - > Deserialize for () { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result<(), E> { - d.expect_null(token) + fn visit_str(&mut self, v: &str) -> Result + where E: Error, + { + let mut iter = v.chars(); + if let Some(v) = iter.next() { + if iter.next().is_some() { + Err(Error::syntax_error()) + } else { + Ok(v) } - } - }; - ( $($name:ident,)+ ) => { - impl< - D: Deserializer, - E, - $($name: Deserialize),* - > Deserialize for ($($name,)*) { - #[inline] - #[allow(non_snake_case)] - fn deserialize_token(d: &mut D, token: Token) -> Result<($($name,)*), E> { - try!(d.expect_tuple_start(token)); - - let result = ($({ - let $name = try!(d.expect_tuple_elt()); - $name - },)*); - - try!(d.expect_tuple_end()); - - Ok(result) - } - } - peel!($($name,)*); - } -} - -impl_deserialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } - -////////////////////////////////////////////////////////////////////////////// - -/// Helper struct that will ignore tokens while taking in consideration -/// recursive structures. -#[derive(Copy)] -pub struct IgnoreTokens; - -impl, E> Deserialize for IgnoreTokens { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - match token { - Token::Option(true) => { - Deserialize::deserialize(d) - } - - Token::EnumStart(_, _, _) => { - loop { - match try!(d.expect_token()) { - Token::End => { return Ok(IgnoreTokens); } - token => { - let _: IgnoreTokens = try!(Deserialize::deserialize_token(d, token)); - } - } - } - } - - Token::StructStart(_, _) => { - loop { - match try!(d.expect_token()) { - Token::End => { return Ok(IgnoreTokens); } - Token::Str(_) | Token::String(_) => { - let _: IgnoreTokens = try!(Deserialize::deserialize(d)); - } - _token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - TokenKind::StrKind, - TokenKind::StringKind, - ]; - return Err(d.syntax_error(token, EXPECTED_TOKENS)); - } - } - } - } - - Token::TupleStart(_) => { - loop { - match try!(d.expect_token()) { - Token::End => { return Ok(IgnoreTokens); } - token => { - let _: IgnoreTokens = try!(Deserialize::deserialize_token(d, token)); - } - } - } - } - - Token::SeqStart(_) => { - loop { - match try!(d.expect_token()) { - Token::End => { return Ok(IgnoreTokens); } - token => { - let _: IgnoreTokens = try!(Deserialize::deserialize_token(d, token)); - } - } - } - } - - Token::MapStart(_) => { - loop { - match try!(d.expect_token()) { - Token::End => { return Ok(IgnoreTokens); } - token => { - let _: IgnoreTokens = try!(Deserialize::deserialize_token(d, token)); - let _: IgnoreTokens = try!(Deserialize::deserialize(d)); - } - } - } - } - - Token::End => { - Err(d.syntax_error(token, COMPOUND_TOKEN_KINDS)) - } - - _ => Ok(IgnoreTokens), + } else { + Err(Error::end_of_stream_error()) } } } -////////////////////////////////////////////////////////////////////////////// - -/// Helper struct that will gather tokens while taking in consideration -/// recursive structures. -pub struct GatherTokens { - tokens: Vec, +impl Deserialize for char { + #[inline] + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer, + { + deserializer.visit(CharVisitor) + } } -impl GatherTokens { +/////////////////////////////////////////////////////////////////////////////// + +struct StringVisitor; + +impl Visitor for StringVisitor { + type Value = String; + + fn visit_str(&mut self, v: &str) -> Result + where E: Error, + { + Ok(v.to_string()) + } + + fn visit_string(&mut self, v: String) -> Result + where E: Error, + { + Ok(v) + } +} + +impl Deserialize for String { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer, + { + deserializer.visit(StringVisitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +struct OptionVisitor { + marker: PhantomData, +} + +impl< + T: Deserialize, +> Visitor for OptionVisitor { + type Value = Option; + #[inline] - pub fn unwrap(self) -> Vec { - self.tokens + fn visit_none(&mut self) -> Result, E> + where E: Error, + { + Ok(None) } #[inline] - fn gather, E>(&mut self, d: &mut D) -> Result<(), E> { - let token = try!(d.expect_token()); - self.gather_token(d, token) + fn visit_some(&mut self, deserializer: &mut D) -> Result, D::Error> + where D: Deserializer, + { + Ok(Some(try!(Deserialize::deserialize(deserializer)))) } +} - #[inline] - fn gather_token, E>(&mut self, d: &mut D, token: Token) -> Result<(), E> { - match token { - token @ Token::Option(true) => { - self.tokens.push(token); - self.gather(d) - } - Token::EnumStart(name, variant, len) => { - self.tokens.reserve(len + 1); - self.tokens.push(Token::EnumStart(name, variant, len)); - self.gather_seq(d) - } - Token::StructStart(name, len) => { - self.tokens.reserve(len + 1); - self.tokens.push(Token::StructStart(name, len)); - self.gather_struct(d) - } - Token::TupleStart(len) => { - self.tokens.reserve(len + 1); - self.tokens.push(Token::TupleStart(len)); - self.gather_seq(d) - } - Token::SeqStart(len) => { - self.tokens.reserve(len + 1); - self.tokens.push(Token::SeqStart(len)); - self.gather_seq(d) - } - Token::MapStart(len) => { - self.tokens.reserve(len + 1); - self.tokens.push(Token::MapStart(len)); - self.gather_map(d) - } - Token::End => { - Err(d.syntax_error(token, COMPOUND_TOKEN_KINDS)) - } - token => { - self.tokens.push(token); - Ok(()) - } - } +impl Deserialize for Option where T: Deserialize { + fn deserialize(deserializer: &mut D) -> Result, D::Error> + where D: Deserializer, + { + deserializer.visit_option(OptionVisitor { marker: PhantomData }) } +} - #[inline] - fn gather_seq, E>(&mut self, d: &mut D) -> Result<(), E> { - loop { - match try!(d.expect_token()) { - token @ Token::End => { - self.tokens.push(token); - return Ok(()); - } - token => { - try!(self.gather_token(d, token)); - } - } - } - } +/////////////////////////////////////////////////////////////////////////////// - #[inline] - fn gather_struct, E>(&mut self, d: &mut D) -> Result<(), E> { - loop { - match try!(d.expect_token()) { - token @ Token::End => { - self.tokens.push(token); - return Ok(()); - } - token @ Token::Str(_) | token @ Token::String(_) => { - self.tokens.push(token); - try!(self.gather(d)) - } - token => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - TokenKind::StrKind, - TokenKind::StringKind, - ]; - return Err(d.syntax_error(token, EXPECTED_TOKENS)); - } - } - } - } +pub struct VecVisitor { + marker: PhantomData, +} - #[inline] - fn gather_map, E>(&mut self, d: &mut D) -> Result<(), E> { - loop { - match try!(d.expect_token()) { - Token::End => { - self.tokens.push(Token::End); - return Ok(()); - } - token => { - try!(self.gather_token(d, token)); - try!(self.gather(d)) - } - } +impl VecVisitor { + pub fn new() -> Self { + VecVisitor { + marker: PhantomData, } } } -impl, E> Deserialize for GatherTokens { +impl Visitor for VecVisitor where T: Deserialize { + type Value = Vec; + #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - let mut tokens = GatherTokens { - tokens: vec!(), - }; - try!(tokens.gather_token(d, token)); - Ok(tokens) + fn visit_seq(&mut self, mut visitor: V) -> Result, V::Error> + where V: SeqVisitor, + { + let (len, _) = visitor.size_hint(); + let mut values = Vec::with_capacity(len); + + while let Some(value) = try!(visitor.visit()) { + values.push(value); + } + + Ok(values) + } +} + +impl Deserialize for Vec { + fn deserialize(deserializer: &mut D) -> Result, D::Error> + where D: Deserializer, + { + deserializer.visit(VecVisitor::new()) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +macro_rules! tuple_impls { + () => {}; + ($($visitor:ident => ($($name:ident),+),)+) => { + $( + struct $visitor<$($name,)+> { + marker: PhantomData<($($name,)+)>, + } + + impl< + $($name: Deserialize,)+ + > Visitor for $visitor<$($name,)+> { + type Value = ($($name,)+); + + #[inline] + #[allow(non_snake_case)] + fn visit_seq(&mut self, mut visitor: V) -> Result<($($name,)+), V::Error> + where V: SeqVisitor, + { + $( + let $name = match try!(visitor.visit()) { + Some(value) => value, + None => { return Err(Error::end_of_stream_error()); } + }; + )+; + + try!(visitor.end()); + + Ok(($($name,)+)) + } + } + + impl< + $($name: Deserialize),+ + > Deserialize for ($($name,)+) { + #[inline] + fn deserialize(deserializer: &mut D) -> Result<($($name,)+), D::Error> + where D: Deserializer, + { + deserializer.visit($visitor { marker: PhantomData }) + } + } + )+ + } +} + +tuple_impls! { + TupleVisitor1 => (T0), + TupleVisitor2 => (T0, T1), + TupleVisitor3 => (T0, T1, T2), + TupleVisitor4 => (T0, T1, T2, T3), + TupleVisitor5 => (T0, T1, T2, T3, T4), + TupleVisitor6 => (T0, T1, T2, T3, T4, T5), + TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), + TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), + TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), + TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), + TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), + TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), +} + +/////////////////////////////////////////////////////////////////////////////// + +pub struct HashMapVisitor { + marker: PhantomData>, +} + +impl HashMapVisitor { + #[inline] + pub fn new() -> Self { + HashMapVisitor { + marker: PhantomData, + } + } +} + +impl Visitor for HashMapVisitor + where K: Deserialize + Eq + Hash, + V: Deserialize, +{ + type Value = HashMap; + + #[inline] + fn visit_map(&mut self, mut visitor: V_) -> Result, V_::Error> + where V_: MapVisitor, + { + let (len, _) = visitor.size_hint(); + let mut values = HashMap::with_capacity(len); + + while let Some((key, value)) = try!(visitor.visit()) { + values.insert(key, value); + } + + Ok(values) + } +} + +impl Deserialize for HashMap + where K: Deserialize + Eq + Hash, + V: Deserialize, +{ + fn deserialize(deserializer: &mut D) -> Result, D::Error> + where D: Deserializer, + { + deserializer.visit(HashMapVisitor::new()) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +pub struct BTreeMapVisitor { + marker: PhantomData>, +} + +impl BTreeMapVisitor { + #[inline] + pub fn new() -> Self { + BTreeMapVisitor { + marker: PhantomData, + } + } +} + +impl Visitor for BTreeMapVisitor + where K: Deserialize + Ord, + V: Deserialize +{ + type Value = BTreeMap; + + #[inline] + fn visit_map(&mut self, mut visitor: Visitor) -> Result, Visitor::Error> + where Visitor: MapVisitor, + { + let mut values = BTreeMap::new(); + + while let Some((key, value)) = try!(visitor.visit()) { + values.insert(key, value); + } + + Ok(values) + } +} + +impl< + K: Deserialize + Eq + Ord, + V: Deserialize, +> Deserialize for BTreeMap { + fn deserialize(deserializer: &mut D) -> Result, D::Error> + where D: Deserializer, + { + deserializer.visit(BTreeMapVisitor::new()) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +struct PathBufVisitor; + +impl Visitor for PathBufVisitor { + type Value = path::PathBuf; + + fn visit_str(&mut self, v: &str) -> Result + where E: Error, + { + Ok(path::PathBuf::new(&v)) + } + + fn visit_string(&mut self, v: String) -> Result + where E: Error, + { + self.visit_str(&v) + } +} + +impl Deserialize for path::PathBuf { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer, + { + deserializer.visit(PathBufVisitor) } } diff --git a/src/json/builder.rs b/src/json/builder.rs index 843b86cc..3db2c4ed 100644 --- a/src/json/builder.rs +++ b/src/json/builder.rs @@ -10,7 +10,8 @@ use std::collections::BTreeMap; -use json::value::{ToJson, Value}; +use ser::{self, Serialize}; +use json::value::{self, Value}; pub struct ArrayBuilder { array: Vec, @@ -25,24 +26,25 @@ impl ArrayBuilder { Value::Array(self.array) } - pub fn push(self, value: T) -> ArrayBuilder { - let mut builder = self; - builder.array.push(value.to_json()); - builder + pub fn push(mut self, v: T) -> ArrayBuilder { + self.array.push(value::to_value(&v)); + self } - pub fn push_array(self, f: F) -> ArrayBuilder where + pub fn push_array(mut self, f: F) -> ArrayBuilder where F: FnOnce(ArrayBuilder) -> ArrayBuilder { let builder = ArrayBuilder::new(); - self.push(f(builder).unwrap()) + self.array.push(f(builder).unwrap()); + self } - pub fn push_object(self, f: F) -> ArrayBuilder where + pub fn push_object(mut self, f: F) -> ArrayBuilder where F: FnOnce(ObjectBuilder) -> ObjectBuilder { let builder = ObjectBuilder::new(); - self.push(f(builder).unwrap()) + self.array.push(f(builder).unwrap()); + self } } @@ -59,77 +61,24 @@ impl ObjectBuilder { Value::Object(self.object) } - pub fn insert(self, key: String, value: V) -> ObjectBuilder { - let mut builder = self; - builder.object.insert(key, value.to_json()); - builder + pub fn insert(mut self, k: String, v: V) -> ObjectBuilder { + self.object.insert(k, value::to_value(&v)); + self } - pub fn insert_array(self, key: String, f: F) -> ObjectBuilder where + pub fn insert_array(mut self, key: String, f: F) -> ObjectBuilder where F: FnOnce(ArrayBuilder) -> ArrayBuilder { let builder = ArrayBuilder::new(); - self.insert(key, f(builder).unwrap()) + self.object.insert(key, f(builder).unwrap()); + self } - pub fn insert_object(self, key: String, f: F) -> ObjectBuilder where + pub fn insert_object(mut self, key: String, f: F) -> ObjectBuilder where F: FnOnce(ObjectBuilder) -> ObjectBuilder { let builder = ObjectBuilder::new(); - self.insert(key, f(builder).unwrap()) - } -} - -#[cfg(test)] -mod tests { - use std::collections::BTreeMap; - - use json::value::Value; - use super::{ArrayBuilder, ObjectBuilder}; - - #[test] - fn test_array_builder() { - let value = ArrayBuilder::new().unwrap(); - assert_eq!(value, Value::Array(Vec::new())); - - let value = ArrayBuilder::new() - .push(1is) - .push(2is) - .push(3is) - .unwrap(); - assert_eq!(value, Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3)))); - - let value = ArrayBuilder::new() - .push_array(|bld| bld.push(1is).push(2is).push(3is)) - .unwrap(); - assert_eq!(value, Value::Array(vec!(Value::Array(vec!(Value::Integer(1), Value::Integer(2), Value::Integer(3)))))); - - let value = ArrayBuilder::new() - .push_object(|bld| - bld - .insert("a".to_string(), 1is) - .insert("b".to_string(), 2is)) - .unwrap(); - - let mut map = BTreeMap::new(); - map.insert("a".to_string(), Value::Integer(1)); - map.insert("b".to_string(), Value::Integer(2)); - assert_eq!(value, Value::Array(vec!(Value::Object(map)))); - } - - #[test] - fn test_object_builder() { - let value = ObjectBuilder::new().unwrap(); - assert_eq!(value, Value::Object(BTreeMap::new())); - - let value = ObjectBuilder::new() - .insert("a".to_string(), 1is) - .insert("b".to_string(), 2is) - .unwrap(); - - let mut map = BTreeMap::new(); - map.insert("a".to_string(), Value::Integer(1)); - map.insert("b".to_string(), Value::Integer(2)); - assert_eq!(value, Value::Object(map)); + self.object.insert(key, f(builder).unwrap()); + self } } diff --git a/src/json/de.rs b/src/json/de.rs index 7e59aabd..f0f96edb 100644 --- a/src/json/de.rs +++ b/src/json/de.rs @@ -1,110 +1,50 @@ -use std::str; +use std::char; use std::num::Float; use unicode::str::Utf16Item; -use std::char; +use std::str; use de; - use super::error::{Error, ErrorCode}; -#[derive(PartialEq, Debug)] -enum State { - // Parse a value. - Value, - // Parse a value or ']'. - ListStart, - // Parse ',' or ']' after an element in a list. - ListCommaOrEnd, - // Parse a key:value or an ']'. - ObjectStart, - // Parse ',' or ']' after an element in an object. - ObjectCommaOrEnd, - // Parse a key in an object. - //ObjectKey, - // Parse a value in an object. - ObjectValue, -} - -/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming -/// an iterator of char. -pub struct Parser { +pub struct Deserializer { rdr: Iter, ch: Option, line: usize, col: usize, - // A state machine is kept to make it possible to interupt and resume parsing. - state_stack: Vec, buf: Vec, } -impl> Iterator for Parser { - type Item = Result; - - #[inline] - fn next(&mut self) -> Option> { - let state = match self.state_stack.pop() { - Some(state) => state, - None => { - // If we have no state left, then we're expecting the structure - // to be done, so make sure there are no trailing characters. - - self.parse_whitespace(); - - if self.eof() { - return None; - } else { - return Some(Err(self.error(ErrorCode::TrailingCharacters))); - } - } - }; - - match state { - State::Value => Some(self.parse_value()), - State::ListStart => Some(self.parse_list_start()), - State::ListCommaOrEnd => Some(self.parse_list_comma_or_end()), - State::ObjectStart => { - match self.parse_object_start() { - Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))), - Ok(None) => Some(Ok(de::Token::End)), - Err(err) => Some(Err(err)), - } - } - State::ObjectCommaOrEnd => { - match self.parse_object_comma_or_end() { - Ok(Some(s)) => Some(Ok(de::Token::String(s.to_string()))), - Ok(None) => Some(Ok(de::Token::End)), - Err(err) => Some(Err(err)), - } - } - //State::ObjectKey => Some(self.parse_object_key()), - State::ObjectValue => Some(self.parse_object_value()), - } - } -} - -impl> Parser { +impl Deserializer + where Iter: Iterator, +{ /// Creates the JSON parser. #[inline] - pub fn new(rdr: Iter) -> Parser { - let mut p = Parser { + pub fn new(rdr: Iter) -> Deserializer { + let mut p = Deserializer { rdr: rdr, ch: Some(b'\x00'), line: 1, col: 0, - state_stack: vec!(State::Value), buf: Vec::with_capacity(128), }; p.bump(); return p; } - #[inline(always)] + #[inline] + pub fn end(&mut self) -> Result<(), Error> { + self.parse_whitespace(); + if self.eof() { + Ok(()) + } else { + Err(self.error(ErrorCode::TrailingCharacters)) + } + } + fn eof(&self) -> bool { self.ch.is_none() } - #[inline] fn ch_or_null(&self) -> u8 { self.ch.unwrap_or(b'\x00') } - #[inline(always)] fn bump(&mut self) { self.ch = self.rdr.next(); @@ -116,23 +56,19 @@ impl> Parser { } } - #[inline] fn next_char(&mut self) -> Option { self.bump(); self.ch } - #[inline(always)] fn ch_is(&self, c: u8) -> bool { self.ch == Some(c) } - #[inline] fn error(&mut self, reason: ErrorCode) -> Error { Error::SyntaxError(reason, self.line, self.col) } - #[inline] fn parse_whitespace(&mut self) { while self.ch_is(b' ') || self.ch_is(b'\n') || @@ -140,8 +76,9 @@ impl> Parser { self.ch_is(b'\r') { self.bump(); } } - #[inline] - fn parse_value(&mut self) -> Result { + fn parse_value(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { self.parse_whitespace(); if self.eof() { @@ -149,22 +86,31 @@ impl> Parser { } match self.ch_or_null() { - b'n' => self.parse_ident(b"ull", de::Token::Null), - b't' => self.parse_ident(b"rue", de::Token::Bool(true)), - b'f' => self.parse_ident(b"alse", de::Token::Bool(false)), - b'0' ... b'9' | b'-' => self.parse_number(), + b'n' => { + try!(self.parse_ident(b"ull")); + visitor.visit_unit() + } + b't' => { + try!(self.parse_ident(b"rue")); + visitor.visit_bool(true) + } + b'f' => { + try!(self.parse_ident(b"alse")); + visitor.visit_bool(false) + } + b'0' ... b'9' | b'-' => self.parse_number(visitor), b'"' => { - Ok(de::Token::String(try!(self.parse_string()).to_string())) + try!(self.parse_string()); + let s = str::from_utf8(&self.buf).unwrap(); + visitor.visit_str(s) } b'[' => { self.bump(); - self.state_stack.push(State::ListStart); - Ok(de::Token::SeqStart(0)) + visitor.visit_seq(SeqVisitor::new(self)) } b'{' => { self.bump(); - self.state_stack.push(State::ObjectStart); - Ok(de::Token::MapStart(0)) + visitor.visit_map(MapVisitor::new(self)) } _ => { Err(self.error(ErrorCode::ExpectedSomeValue)) @@ -172,18 +118,18 @@ impl> Parser { } } - #[inline] - fn parse_ident(&mut self, ident: &[u8], token: de::Token) -> Result { + fn parse_ident(&mut self, ident: &[u8]) -> Result<(), Error> { if ident.iter().all(|c| Some(*c) == self.next_char()) { self.bump(); - Ok(token) + Ok(()) } else { Err(self.error(ErrorCode::ExpectedSomeIdent)) } } - #[inline] - fn parse_number(&mut self) -> Result { + fn parse_number(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { let mut neg = 1; if self.ch_is(b'-') { @@ -205,13 +151,12 @@ impl> Parser { res = try!(self.parse_exponent(res)); } - Ok(de::Token::F64(neg * res)) + visitor.visit_f64(neg * res) } else { - Ok(de::Token::I64(neg * res)) + visitor.visit_i64(neg * res) } } - #[inline] fn parse_integer(&mut self) -> Result { let mut res = 0; @@ -245,7 +190,6 @@ impl> Parser { Ok(res) } - #[inline] fn parse_decimal(&mut self, res: f64) -> Result { self.bump(); @@ -261,7 +205,7 @@ impl> Parser { match self.ch_or_null() { c @ b'0' ... b'9' => { dec /= 10.0; - res += (((c as isize) - (b'0' as isize)) as f64) * dec; + res += (((c as u64) - (b'0' as u64)) as f64) * dec; self.bump(); } _ => break, @@ -271,11 +215,10 @@ impl> Parser { Ok(res) } - #[inline] fn parse_exponent(&mut self, mut res: f64) -> Result { self.bump(); - let mut exp = 0us; + let mut exp = 0; let mut neg_exp = false; if self.ch_is(b'+') { @@ -294,7 +237,7 @@ impl> Parser { match self.ch_or_null() { c @ b'0' ... b'9' => { exp *= 10; - exp += (c as usize) - (b'0' as usize); + exp += (c as i32) - (b'0' as i32); self.bump(); } @@ -302,7 +245,7 @@ impl> Parser { } } - let exp: f64 = 10_f64.powi(exp as i32); + let exp: f64 = 10_f64.powi(exp); if neg_exp { res /= exp; } else { @@ -312,11 +255,10 @@ impl> Parser { Ok(res) } - #[inline] fn decode_hex_escape(&mut self) -> Result { - let mut i = 0us; + let mut i = 0; let mut n = 0u16; - while i < 4us && !self.eof() { + while i < 4 && !self.eof() { self.bump(); n = match self.ch_or_null() { c @ b'0' ... b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)), @@ -329,19 +271,18 @@ impl> Parser { _ => { return Err(self.error(ErrorCode::InvalidEscape)); } }; - i += 1us; + i += 1; } // Error out if we didn't parse 4 digits. - if i != 4us { + if i != 4 { return Err(self.error(ErrorCode::InvalidEscape)); } Ok(n) } - #[inline] - fn parse_string(&mut self) -> Result<&str, Error> { + fn parse_string(&mut self) -> Result<(), Error> { self.buf.clear(); let mut escape = false; @@ -397,7 +338,7 @@ impl> Parser { } }; - let buf = &mut [0u8; 4]; + let buf = &mut [0; 4]; let len = c.encode_utf8(buf).unwrap_or(0); self.buf.extend(buf[..len].iter().map(|b| *b)); } @@ -410,7 +351,7 @@ impl> Parser { match ch { b'"' => { self.bump(); - return Ok(str::from_utf8(&self.buf).unwrap()); + return Ok(()); } b'\\' => { escape = true; @@ -423,92 +364,12 @@ impl> Parser { } } - #[inline] - fn parse_list_start(&mut self) -> Result { - self.parse_whitespace(); - - if self.ch_is(b']') { - self.bump(); - Ok(de::Token::End) - } else { - self.state_stack.push(State::ListCommaOrEnd); - self.parse_value() - } - } - - #[inline] - fn parse_list_comma_or_end(&mut self) -> Result { - self.parse_whitespace(); - - if self.ch_is(b',') { - self.bump(); - self.state_stack.push(State::ListCommaOrEnd); - self.parse_value() - } else if self.ch_is(b']') { - self.bump(); - Ok(de::Token::End) - } else if self.eof() { - Err(self.error(ErrorCode::EOFWhileParsingList)) - } else { - Err(self.error(ErrorCode::ExpectedListCommaOrEnd)) - } - } - - #[inline] - fn parse_object_start(&mut self) -> Result, Error> { - self.parse_whitespace(); - - if self.ch_is(b'}') { - self.bump(); - Ok(None) - } else { - Ok(Some(try!(self.parse_object_key()))) - } - } - - #[inline] - fn parse_object_comma_or_end(&mut self) -> Result, Error> { - self.parse_whitespace(); - - if self.ch_is(b',') { - self.bump(); - Ok(Some(try!(self.parse_object_key()))) - } else if self.ch_is(b'}') { - self.bump(); - Ok(None) - } else if self.eof() { - Err(self.error(ErrorCode::EOFWhileParsingObject)) - } else { - Err(self.error(ErrorCode::ExpectedObjectCommaOrEnd)) - } - } - - #[inline] - fn parse_object_key(&mut self) -> Result<&str, Error> { - self.parse_whitespace(); - - if self.eof() { - return Err(self.error(ErrorCode::EOFWhileParsingString)); - } - - match self.ch_or_null() { - b'"' => { - self.state_stack.push(State::ObjectValue); - - Ok(try!(self.parse_string())) - } - _ => Err(self.error(ErrorCode::KeyMustBeAString)), - } - } - - #[inline] - fn parse_object_value(&mut self) -> Result { + fn parse_object_colon(&mut self) -> Result<(), Error> { self.parse_whitespace(); if self.ch_is(b':') { self.bump(); - self.state_stack.push(State::ObjectCommaOrEnd); - self.parse_value() + Ok(()) } else if self.eof() { Err(self.error(ErrorCode::EOFWhileParsingObject)) } else { @@ -517,148 +378,259 @@ impl> Parser { } } -impl> de::Deserializer for Parser { - fn end_of_stream_error(&mut self) -> Error { - Error::SyntaxError(ErrorCode::EOFWhileParsingValue, self.line, self.col) - } +impl de::Deserializer for Deserializer + where Iter: Iterator, +{ + type Error = Error; - fn syntax_error(&mut self, token: de::Token, expected: &'static [de::TokenKind]) -> Error { - Error::SyntaxError(ErrorCode::ExpectedTokens(token, expected), self.line, self.col) - } - - fn unexpected_name_error(&mut self, token: de::Token) -> Error { - Error::SyntaxError(ErrorCode::UnexpectedName(token), self.line, self.col) - } - - fn conversion_error(&mut self, token: de::Token) -> Error { - Error::SyntaxError(ErrorCode::ConversionError(token), self.line, self.col) + #[inline] + fn visit(&mut self, visitor: V) -> Result + where V: de::Visitor, + { + self.parse_value(visitor) } #[inline] - fn missing_field< - T: de::Deserialize, Error> - >(&mut self, _field: &'static str) -> Result { - // JSON can represent `null` values as a missing value, so this isn't - // necessarily an error. - de::Deserialize::deserialize_token(self, de::Token::Null) - } + fn visit_option(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + self.parse_whitespace(); - // Special case treating options as a nullable value. - #[inline] - fn expect_option< - U: de::Deserialize, Error> - >(&mut self, token: de::Token) -> Result, Error> { - match token { - de::Token::Null => Ok(None), - token => { - let value: U = try!(de::Deserialize::deserialize_token(self, token)); - Ok(Some(value)) - } - } - } - - // Special case treating enums as a `{"": []}`. - #[inline] - fn expect_enum_start(&mut self, - token: de::Token, - _name: &str, - variants: &[&str]) -> Result { - match token { - de::Token::MapStart(_) => { } - _ => { return Err(self.error(ErrorCode::ExpectedEnumMapStart)); } - }; - - // Enums only have one field in them, which is the variant name. - let variant = match try!(self.expect_token()) { - de::Token::String(variant) => variant, - _ => { return Err(self.error(ErrorCode::ExpectedEnumVariantString)); } - }; - - // The variant's field is a list of the values. - match try!(self.expect_token()) { - de::Token::SeqStart(_) => { } - _ => { return Err(self.error(ErrorCode::ExpectedEnumToken)); } + if self.eof() { + return Err(self.error(ErrorCode::EOFWhileParsingValue)); } - match variants.iter().position(|v| *v == &variant[]) { - Some(idx) => Ok(idx), - None => Err(self.error(ErrorCode::UnknownVariant)), - } - } - - fn expect_enum_end(&mut self) -> Result<(), Error> { - // There will be one `End` for the list, and one for the object. - match try!(self.expect_token()) { - de::Token::End => { - match try!(self.expect_token()) { - de::Token::End => Ok(()), - _ => Err(self.error(ErrorCode::ExpectedEnumEndToken)), - } - } - _ => Err(self.error(ErrorCode::ExpectedEnumEnd)), + if self.ch_is(b'n') { + try!(self.parse_ident(b"ull")); + visitor.visit_none() + } else { + visitor.visit_some(self) } } #[inline] - fn expect_struct_start(&mut self, token: de::Token, _name: &str) -> Result<(), Error> { - match token { - de::Token::MapStart(_) => Ok(()), - _ => { - static EXPECTED_TOKENS: &'static [de::TokenKind] = &[ - de::TokenKind::MapStartKind, - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) + fn visit_enum(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + self.parse_whitespace(); + + if self.ch_is(b'{') { + self.bump(); + self.parse_whitespace(); + + try!(self.parse_string()); + try!(self.parse_object_colon()); + + let variant = str::from_utf8(&self.buf).unwrap().to_string(); + + let value = try!(visitor.visit_variant(&variant, EnumVisitor { + de: self, + })); + + self.parse_whitespace(); + + if self.ch_is(b'}') { + self.bump(); + Ok(value) + } else { + return Err(self.error(ErrorCode::ExpectedSomeValue)); } + } else { + Err(self.error(ErrorCode::ExpectedSomeValue)) + } + } +} + +struct SeqVisitor<'a, Iter: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, Iter> SeqVisitor<'a, Iter> { + fn new(de: &'a mut Deserializer) -> Self { + SeqVisitor { + de: de, + first: true, + } + } +} + +impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter> + where Iter: Iterator +{ + type Error = Error; + + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize, + { + self.de.parse_whitespace(); + + if self.de.ch_is(b']') { + self.de.bump(); + return Ok(None); + } + + if self.first { + self.first = false; + } else { + if self.de.ch_is(b',') { + self.de.bump(); + } else if self.de.eof() { + return Err(self.de.error(ErrorCode::EOFWhileParsingList)); + } else { + return Err(self.de.error(ErrorCode::ExpectedListCommaOrEnd)); + } + } + + let value = try!(de::Deserialize::deserialize(self.de)); + Ok(Some(value)) + } + + fn end(&mut self) -> Result<(), Error> { + self.de.parse_whitespace(); + + if self.de.ch_is(b']') { + self.de.bump(); + Ok(()) + } else if self.de.eof() { + Err(self.de.error(ErrorCode::EOFWhileParsingList)) + } else { + Err(self.de.error(ErrorCode::TrailingCharacters)) + } + } +} + +struct MapVisitor<'a, Iter: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, Iter> MapVisitor<'a, Iter> { + fn new(de: &'a mut Deserializer) -> Self { + MapVisitor { + de: de, + first: true, + } + } +} + +impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter> + where Iter: Iterator +{ + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where K: de::Deserialize, + { + self.de.parse_whitespace(); + + if self.de.ch_is(b'}') { + self.de.bump(); + return Ok(None); + } + + if self.first { + self.first = false; + } else { + if self.de.ch_is(b',') { + self.de.bump(); + self.de.parse_whitespace(); + } else if self.de.eof() { + return Err(self.de.error(ErrorCode::EOFWhileParsingObject)); + } else { + return Err(self.de.error(ErrorCode::ExpectedObjectCommaOrEnd)); + } + } + + if self.de.eof() { + return Err(self.de.error(ErrorCode::EOFWhileParsingValue)); + } + + if !self.de.ch_is(b'"') { + return Err(self.de.error(ErrorCode::KeyMustBeAString)); + } + + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + + fn visit_value(&mut self) -> Result + where V: de::Deserialize, + { + try!(self.de.parse_object_colon()); + + Ok(try!(de::Deserialize::deserialize(self.de))) + } + + fn end(&mut self) -> Result<(), Error> { + self.de.parse_whitespace(); + + if self.de.ch_is(b']') { + self.de.bump(); + Ok(()) + } else if self.de.eof() { + Err(self.de.error(ErrorCode::EOFWhileParsingList)) + } else { + Err(self.de.error(ErrorCode::TrailingCharacters)) + } + } +} + +struct EnumVisitor<'a, Iter: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter> + where Iter: Iterator, +{ + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self.de) + } + + fn visit_seq(&mut self, mut visitor: V) -> Result + where V: de::EnumSeqVisitor, + { + self.de.parse_whitespace(); + + if self.de.ch_is(b'[') { + self.de.bump(); + visitor.visit(SeqVisitor::new(self.de)) + } else { + Err(self.de.error(ErrorCode::ExpectedSomeValue)) } } - #[inline] - fn expect_struct_field_or_end(&mut self, - fields: &'static [&'static str] - ) -> Result>, Error> { - let result = match self.state_stack.pop() { - Some(State::ObjectStart) => { - try!(self.parse_object_start()) - } - Some(State::ObjectCommaOrEnd) => { - try!(self.parse_object_comma_or_end()) - } - _ => panic!("invalid internal state"), - }; + fn visit_map(&mut self, mut visitor: V) -> Result + where V: de::EnumMapVisitor, + { + self.de.parse_whitespace(); - let s = match result { - Some(s) => s, - None => { return Ok(None); } - }; - - Ok(Some(fields.iter().position(|field| *field == &s[]))) + if self.de.ch_is(b'{') { + self.de.bump(); + visitor.visit(MapVisitor::new(self.de)) + } else { + Err(self.de.error(ErrorCode::ExpectedSomeValue)) + } } } /// Decodes a json value from an `Iterator`. -pub fn from_iter< - Iter: Iterator, - T: de::Deserialize, Error> ->(iter: Iter) -> Result { - let mut parser = Parser::new(iter); - let value = try!(de::Deserialize::deserialize(&mut parser)); +pub fn from_iter(iter: I) -> Result + where I: Iterator, + T: de::Deserialize +{ + let mut de = Deserializer::new(iter); + let value = try!(de::Deserialize::deserialize(&mut de)); // Make sure the whole stream has been consumed. - match parser.next() { - Some(Ok(_token)) => Err(parser.error(ErrorCode::TrailingCharacters)), - Some(Err(err)) => Err(err), - None => Ok(value), - } + try!(de.end()); + Ok(value) } /// Decodes a json value from a string -pub fn from_str< - 'a, - T: de::Deserialize>, Error> ->(s: &'a str) -> Result { +pub fn from_str<'a, T>(s: &'a str) -> Result + where T: de::Deserialize +{ from_iter(s.bytes()) } - -#[cfg(test)] -mod tests { -} diff --git a/src/json/error.rs b/src/json/error.rs index 6df233e3..430b0b04 100644 --- a/src/json/error.rs +++ b/src/json/error.rs @@ -2,12 +2,11 @@ use std::error; use std::fmt; use std::io; -use de::{Token, TokenKind}; +use de; /// The errors that can arise while parsing a JSON stream. -#[derive(Clone, PartialEq)] +#[derive(Copy, Clone, PartialEq)] pub enum ErrorCode { - ConversionError(Token), EOFWhileParsingList, EOFWhileParsingObject, EOFWhileParsingString, @@ -24,7 +23,6 @@ pub enum ErrorCode { ExpectedObjectCommaOrEnd, ExpectedSomeIdent, ExpectedSomeValue, - ExpectedTokens(Token, &'static [TokenKind]), InvalidEscape, InvalidNumber, InvalidUnicodeCodePoint, @@ -35,15 +33,16 @@ pub enum ErrorCode { NotUtf8, TrailingCharacters, UnexpectedEndOfHexEscape, - UnexpectedName(Token), UnknownVariant, UnrecognizedHex, } impl fmt::Debug for ErrorCode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use std::fmt::Debug; + match *self { - ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {:?}", token), + //ErrorCode::ConversionError(ref token) => write!(f, "failed to convert {}", token), ErrorCode::EOFWhileParsingList => "EOF While parsing list".fmt(f), ErrorCode::EOFWhileParsingObject => "EOF While parsing object".fmt(f), ErrorCode::EOFWhileParsingString => "EOF While parsing string".fmt(f), @@ -60,7 +59,7 @@ impl fmt::Debug for ErrorCode { ErrorCode::ExpectedObjectCommaOrEnd => "expected `,` or `}`".fmt(f), ErrorCode::ExpectedSomeIdent => "expected ident".fmt(f), ErrorCode::ExpectedSomeValue => "expected value".fmt(f), - ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {:?}, found {:?}", tokens, token), + //ErrorCode::ExpectedTokens(ref token, tokens) => write!(f, "expected {}, found {}", tokens, token), ErrorCode::InvalidEscape => "invalid escape".fmt(f), ErrorCode::InvalidNumber => "invalid number".fmt(f), ErrorCode::InvalidUnicodeCodePoint => "invalid unicode code point".fmt(f), @@ -71,7 +70,7 @@ impl fmt::Debug for ErrorCode { ErrorCode::NotUtf8 => "contents not utf-8".fmt(f), ErrorCode::TrailingCharacters => "trailing characters".fmt(f), ErrorCode::UnexpectedEndOfHexEscape => "unexpected end of hex escape".fmt(f), - ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {:?}", name), + //ErrorCode::UnexpectedName(ref name) => write!(f, "unexpected name {}", name), ErrorCode::UnknownVariant => "unknown variant".fmt(f), ErrorCode::UnrecognizedHex => "invalid \\u escape (unrecognized hex)".fmt(f), } @@ -83,39 +82,59 @@ pub enum Error { /// msg, line, col SyntaxError(ErrorCode, usize, usize), IoError(io::Error), + /* ExpectedError(String, String), - MissingFieldError(String), + */ + MissingFieldError(&'static str), + /* UnknownVariantError(String), + */ } impl error::Error for Error { fn description(&self) -> &str { match *self { Error::SyntaxError(..) => "syntax error", - Error::IoError(_) => "Input/Output error", + Error::IoError(ref error) => error.description(), + /* Error::ExpectedError(ref expected, _) => &expected, + */ Error::MissingFieldError(_) => "missing field", + /* Error::UnknownVariantError(_) => "unknown variant", + */ } } + + fn cause(&self) -> Option<&error::Error> { + match *self { + Error::IoError(ref error) => Some(error), + _ => None, + } + } + } impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { match *self { Error::SyntaxError(ref code, line, col) => { - write!(fmt, "{:?} at line {:?} column {:?}", code, line, col) + write!(fmt, "{:?} at line {} column {}", code, line, col) } Error::IoError(ref error) => fmt::Display::fmt(error, fmt), + /* Error::ExpectedError(ref expected, ref found) => { - write!(fmt, "expected {:?}, found {:?}", expected, found) + Some(format!("expected {}, found {}", expected, found)) } + */ Error::MissingFieldError(ref field) => { - write!(fmt, "missing field {:?}", field) + write!(fmt, "missing field {}", field) } + /* Error::UnknownVariantError(ref variant) => { - write!(fmt, "unknown variant {:?}", variant) + Some(format!("unknown variant {}", variant)) } + */ } } } @@ -125,3 +144,17 @@ impl error::FromError for Error { Error::IoError(error) } } + +impl de::Error for Error { + fn syntax_error() -> Error { + Error::SyntaxError(ErrorCode::ExpectedSomeValue, 0, 0) + } + + fn end_of_stream_error() -> Error { + Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0) + } + + fn missing_field_error(field: &'static str) -> Error { + Error::MissingFieldError(field) + } +} diff --git a/src/json/mod.rs b/src/json/mod.rs index 51c85fc1..4c1c6716 100644 --- a/src/json/mod.rs +++ b/src/json/mod.rs @@ -1,317 +1,19 @@ -// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Rust JSON serialization library -// Copyright (c) 2011 Google Inc. - -#![forbid(non_camel_case_types)] -#![allow(missing_docs)] - -/*! -JSON parsing and serialization - -# What is JSON? - -JSON (JavaScript Object Notation) is a way to write data in Javascript. -Like XML it allows one to serialize structured data in a text format that can be read by humans -easily. -Its native compatibility with JavaScript and its simple syntax make it used widely. - -Json data are serialized in a form of "key":"value". -Data types that can be serialized are JavaScript types : -boolean (`true` or `false`), number (`f64`), string, array, object, null. -An object is a series of string keys mapping to values, in `"key": value` format. -Arrays are enclosed in square brackets (&[ ... ]) and objects in curly brackets ({ ... }). -A simple JSON document serializing a person, his/her age, address and phone numbers could look like: - -```ignore -{ - "FirstName": "John", - "LastName": "Doe", - "Age": 43, - "Address": { - "Street": "Downing Street 10", - "City": "London", - "Country": "Great Britain" - }, - "PhoneNumbers": [ - "+44 1234567", - "+44 2345678" - ] -} -``` - -# Rust Type-based Serializing and Deserializing - -Rust provides a mechanism for low boilerplate serializing and deserializing -of values to and from JSON via the serialization API. -To be able to serialize a piece of data, it must implement the `serde::Serialize` trait. -To be able to deserialize a piece of data, it must implement the `serde::Deserialize` trait. -The Rust compiler provides an annotation to automatically generate -the code for these traits: `#[derive_serialize]` and `#[derive_deserialize]`. - -To serialize using `Serialize`: - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use std::io::WriteExt; -use serde::json; -use serde::Serialize; - -#[derive_serialize] -pub struct TestStruct { - data_str: String, -} - -fn main() { - let to_serialize_object = TestStruct { - data_str: "example of string to serialize".to_string() - }; - - let mut wr = Vec::new(); - { - let mut serializer = json::Serializer::new(wr.by_ref()); - match to_serialize_object.serialize(&mut serializer) { - Ok(()) => (), - Err(e) => panic!("json serialization error: {:?}", e), - } - } -} -``` - -Two wrapper functions are provided to serialize a `Serialize` object -into a string (String) or buffer (~[u8]): `json::to_string(value)` and -`json::to_vec(value)`. - -```rust -use serde::json; -let to_serialize_object = "example of string to serialize"; -let serialized_str: String = json::to_string(&to_serialize_object).unwrap(); -``` - -JSON API provide an enum `json::Value` and a trait `ToJson` to serialize -object. The trait `ToJson` serialize object into a container `json::Value` and -the API provide writer to serialize them into a stream or a string ... - -When using `ToJson` the `Serialize` trait implementation is not mandatory. - -A basic `ToJson` example using a BTreeMap of attribute name / attribute value: - - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use std::collections::BTreeMap; -use serde::json::{ToJson, Value}; - -pub struct MyStruct { - attr1: u8, - attr2: String, -} - -impl ToJson for MyStruct { - fn to_json( &self ) -> Value { - let mut d = BTreeMap::new(); - d.insert("attr1".to_string(), self.attr1.to_json()); - d.insert("attr2".to_string(), self.attr2.to_json()); - d.to_json() - } -} - -fn main() { - let test = MyStruct {attr1: 1, attr2:"test".to_string()}; - let json: Value = test.to_json(); - let json_str: String = json.to_string(); -} -``` - -Or you can use the helper type `ObjectBuilder`: - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use serde::json::{ObjectBuilder, ToJson, Value}; - -pub struct MyStruct { - attr1: u8, - attr2: String, -} - -impl ToJson for MyStruct { - fn to_json( &self ) -> Value { - ObjectBuilder::new() - .insert("attr1".to_string(), &self.attr1) - .insert("attr2".to_string(), &self.attr2) - .unwrap() - } -} - -fn main() { - let test = MyStruct {attr1: 1, attr2:"test".to_string()}; - let json: Value = test.to_json(); - let json_str: String = json.to_string(); -} -``` - -To deserialize a JSON string using `Deserialize` trait: - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use serde::json; -use serde::Deserialize; - -#[derive_deserialize] -pub struct MyStruct { - attr1: u8, - attr2: String, -} - -fn main() { - let json_str_to_deserialize = "{ \"attr1\": 1, \"attr2\": \"toto\" }"; - let mut parser = json::Parser::new(json_str_to_deserialize.bytes()); - let deserialized_object: MyStruct = match Deserialize::deserialize(&mut parser) { - Ok(v) => v, - Err(e) => panic!("Decoding error: {:?}", e) - }; -} -``` - -# Examples of use - -## Using Autoserialization - -Create a struct called `TestStruct1` and serialize and deserialize it to and from JSON -using the serialization API, using the derived serialization code. - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use serde::json; - -#[derive_serialize] -#[derive_deserialize] -pub struct TestStruct1 { - data_int: u8, - data_str: String, - data_vector: Vec, -} - -// To serialize use the `json::to_string` to serialize an object in a string. -// It calls the generated `Serialize` impl. -fn main() { - let to_serialize_object = TestStruct1 { - data_int: 1, - data_str: "toto".to_string(), - data_vector: vec![2,3,4,5] - }; - let serialized_str: String = json::to_string(&to_serialize_object).unwrap(); - - // To deserialize use the `json::from_str` function. - - let deserialized_object: TestStruct1 = match json::from_str(&serialized_str) { - Ok(deserialized_object) => deserialized_object, - Err(e) => panic!("json deserialization error: {:?}", e), - }; -} -``` - -## Using `ToJson` - -This example use the ToJson impl to deserialize the JSON string. -Example of `ToJson` trait implementation for TestStruct1. - -```rust -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use serde::json::ToJson; -use serde::json; -use serde::Deserialize; - -#[derive_serialize] // generate Serialize impl -#[derive_deserialize] // generate Deserialize impl -pub struct TestStruct1 { - data_int: u8, - data_str: String, - data_vector: Vec, -} - -impl ToJson for TestStruct1 { - fn to_json( &self ) -> json::Value { - json::builder::ObjectBuilder::new() - .insert("data_int".to_string(), &self.data_int) - .insert("data_str".to_string(), &self.data_str) - .insert("data_vector".to_string(), &self.data_vector) - .unwrap() - } -} - -fn main() { - // Serialization using our impl of to_json - - let test: TestStruct1 = TestStruct1 { - data_int: 1, - data_str: "toto".to_string(), - data_vector: vec![2,3,4,5], - }; - let json: json::Value = test.to_json(); - let json_str: String = json.to_string(); - - // Deserialize like before. - - let mut parser = json::Parser::new(json_str.bytes()); - let deserialized: TestStruct1 = Deserialize::deserialize(&mut parser).unwrap(); -} -``` - -*/ - -pub use self::builder::{ArrayBuilder, ObjectBuilder}; -pub use self::de::{ - Parser, - from_str, -}; +pub use self::de::{Deserializer, from_str}; pub use self::error::{Error, ErrorCode}; pub use self::ser::{ Serializer, - PrettySerializer, to_writer, + to_writer_pretty, to_vec, + to_vec_pretty, to_string, - to_pretty_writer, - to_pretty_vec, - to_pretty_string, + to_string_pretty, + escape_str, }; -pub use self::value::{Value, ToJson, from_json}; +pub use self::value::{Value, to_value, from_value}; pub mod builder; pub mod de; +pub mod error; pub mod ser; pub mod value; -pub mod error; diff --git a/src/json/ser.rs b/src/json/ser.rs index fa612b74..092f1a1f 100644 --- a/src/json/ser.rs +++ b/src/json/ser.rs @@ -1,498 +1,310 @@ -use std::f32; -use std::f64; -use std::num::{Float, FpCategory}; +use std::{f32, f64}; use std::io; +use std::num::{Float, FpCategory}; use std::string::FromUtf8Error; use ser; /// A structure for implementing serialization to JSON. pub struct Serializer { - wr: W, - first: bool, + writer: W, + format: Format, + current_indent: usize, + indent: usize, +} + +#[derive(Copy, PartialEq)] +enum Format { + Compact, + Pretty, } impl Serializer { - /// Creates a new JSON serializer whose output will be written to the writer + /// Creates a new JSON visitr whose output will be written to the writer /// specified. - pub fn new(wr: W) -> Serializer { + #[inline] + pub fn new(writer: W) -> Serializer { Serializer { - wr: wr, - first: true, - } - } - - /// Unwrap the io::Write from the Serializer. - pub fn unwrap(self) -> W { - self.wr - } -} - -impl ser::Serializer for Serializer { - #[inline] - fn serialize_null(&mut self) -> io::Result<()> { - self.wr.write_all(b"null") - } - - #[inline] - fn serialize_bool(&mut self, value: bool) -> io::Result<()> { - if value { - self.wr.write_all(b"true") - } else { - self.wr.write_all(b"false") - } - } - - #[inline] - fn serialize_isize(&mut self, value: isize) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i8(&mut self, value: i8) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i16(&mut self, value: i16) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i32(&mut self, value: i32) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i64(&mut self, value: i64) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_usize(&mut self, value: usize) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u8(&mut self, value: u8) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u16(&mut self, value: u16) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u32(&mut self, value: u32) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u64(&mut self, value: u64) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_f32(&mut self, value: f32) -> io::Result<()> { - fmt_f32_or_null(&mut self.wr, value) - } - - #[inline] - fn serialize_f64(&mut self, value: f64) -> io::Result<()> { - fmt_f64_or_null(&mut self.wr, value) - } - - #[inline] - fn serialize_char(&mut self, value: char) -> io::Result<()> { - escape_char(&mut self.wr, value) - } - - #[inline] - fn serialize_str(&mut self, value: &str) -> io::Result<()> { - escape_str(&mut self.wr, value) - } - - #[inline] - fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> { - self.first = true; - write!(&mut self.wr, "[") - } - - #[inline] - fn serialize_tuple_elt< - T: ser::Serialize, io::Error> - >(&mut self, value: &T) -> io::Result<()> { - if self.first { - self.first = false; - } else { - try!(write!(&mut self.wr, ",")); - } - value.serialize(self) - } - - #[inline] - fn serialize_tuple_end(&mut self) -> io::Result<()> { - write!(&mut self.wr, "]") - } - - #[inline] - fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> { - self.first = true; - write!(&mut self.wr, "{{") - } - - #[inline] - fn serialize_struct_elt< - T: ser::Serialize, io::Error> - >(&mut self, name: &str, value: &T) -> io::Result<()> { - use ser::Serialize; - - if self.first { - self.first = false; - } else { - try!(write!(&mut self.wr, ",")); - } - try!(name.serialize(self)); - try!(write!(&mut self.wr, ":")); - value.serialize(self) - } - - #[inline] - fn serialize_struct_end(&mut self) -> io::Result<()> { - write!(&mut self.wr, "}}") - } - - #[inline] - fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> { - self.first = true; - try!(write!(&mut self.wr, "{{")); - try!(self.serialize_str(variant)); - write!(&mut self.wr, ":[") - } - - #[inline] - fn serialize_enum_elt< - T: ser::Serialize, io::Error> - >(&mut self, value: &T) -> io::Result<()> { - if self.first { - self.first = false; - } else { - try!(write!(&mut self.wr, ",")); - } - value.serialize(self) - } - - #[inline] - fn serialize_enum_end(&mut self) -> io::Result<()> { - write!(&mut self.wr, "]}}") - } - - #[inline] - fn serialize_option< - T: ser::Serialize, io::Error> - >(&mut self, v: &Option) -> io::Result<()> { - match *v { - Some(ref v) => { - v.serialize(self) - } - None => { - self.serialize_null() - } - } - } - - #[inline] - fn serialize_seq< - T: ser::Serialize, io::Error>, - Iter: Iterator - >(&mut self, iter: Iter) -> io::Result<()> { - try!(write!(&mut self.wr, "[")); - let mut first = true; - for elt in iter { - if first { - first = false; - } else { - try!(write!(&mut self.wr, ",")); - } - try!(elt.serialize(self)); - - } - write!(&mut self.wr, "]") - } - - #[inline] - fn serialize_map< - K: ser::Serialize, io::Error>, - V: ser::Serialize, io::Error>, - Iter: Iterator - >(&mut self, iter: Iter) -> io::Result<()> { - try!(write!(&mut self.wr, "{{")); - let mut first = true; - for (key, value) in iter { - if first { - first = false; - } else { - try!(write!(&mut self.wr, ",")); - } - try!(key.serialize(self)); - try!(write!(&mut self.wr, ":")); - try!(value.serialize(self)); - } - write!(&mut self.wr, "}}") - } -} - -/// Another serializer for JSON, but prints out human-readable JSON instead of -/// compact data -pub struct PrettySerializer { - wr: W, - indent: usize, - first: bool, -} - -impl PrettySerializer { - /// Creates a new serializer whose output will be written to the specified writer - pub fn new(wr: W) -> PrettySerializer { - PrettySerializer { - wr: wr, + writer: writer, + format: Format::Compact, + current_indent: 0, indent: 0, - first: true, } } - /// Unwrap the io::Write from the Serializer. - pub fn unwrap(self) -> W { - self.wr - } - + /// Creates a new JSON visitr whose output will be written to the writer + /// specified. #[inline] - fn serialize_sep(&mut self) -> io::Result<()> { - if self.first { - self.first = false; - self.indent += 2; - try!(write!(&mut self.wr, "\n")); - } else { - try!(write!(&mut self.wr, ",\n")); + pub fn new_pretty(writer: W) -> Serializer { + Serializer { + writer: writer, + format: Format::Pretty, + current_indent: 0, + indent: 2, } - - spaces(&mut self.wr, self.indent) } + /// Unwrap the `Writer` from the `Serializer`. #[inline] - fn serialize_end(&mut self, s: &str) -> io::Result<()> { - if !self.first { - try!(write!(&mut self.wr, "\n")); - self.indent -= 2; - try!(spaces(&mut self.wr, self.indent)); - } - - self.first = false; - - write!(&mut self.wr, "{}", s) + pub fn into_inner(self) -> W { + self.writer } } -impl ser::Serializer for PrettySerializer { - #[inline] - fn serialize_null(&mut self) -> io::Result<()> { - write!(&mut self.wr, "null") - } +impl ser::Serializer for Serializer { + type Value = (); + type Error = io::Error; #[inline] - fn serialize_bool(&mut self, v: bool) -> io::Result<()> { - if v { - self.wr.write_all(b"true") - } else { - self.wr.write_all(b"false") - } + fn visit(&mut self, value: &T) -> io::Result<()> + where T: ser::Serialize, + { + value.visit(&mut Visitor { + writer: &mut self.writer, + format: self.format, + current_indent: self.current_indent, + indent: self.indent, + }) } +} - #[inline] - fn serialize_isize(&mut self, value: isize) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } +struct Visitor<'a, W: 'a> { + writer: &'a mut W, + format: Format, + current_indent: usize, + indent: usize, +} - #[inline] - fn serialize_i8(&mut self, value: i8) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i16(&mut self, value: i16) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i32(&mut self, value: i32) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_i64(&mut self, value: i64) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_usize(&mut self, value: usize) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u8(&mut self, value: u8) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u16(&mut self, value: u16) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u32(&mut self, value: u32) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_u64(&mut self, value: u64) -> io::Result<()> { - write!(&mut self.wr, "{}", value) - } - - #[inline] - fn serialize_f32(&mut self, value: f32) -> io::Result<()> { - fmt_f32_or_null(&mut self.wr, value) - } - - #[inline] - fn serialize_f64(&mut self, value: f64) -> io::Result<()> { - fmt_f64_or_null(&mut self.wr, value) - } - - #[inline] - fn serialize_char(&mut self, value: char) -> io::Result<()> { - escape_char(&mut self.wr, value) - } - - #[inline] - fn serialize_str(&mut self, value: &str) -> io::Result<()> { - escape_str(&mut self.wr, value) - } - - #[inline] - fn serialize_tuple_start(&mut self, _len: usize) -> io::Result<()> { - self.first = true; - self.wr.write_all(b"[") - } - - #[inline] - fn serialize_tuple_elt< - T: ser::Serialize, io::Error> - >(&mut self, value: &T) -> io::Result<()> { - try!(self.serialize_sep()); - value.serialize(self) - } - - #[inline] - fn serialize_tuple_end(&mut self) -> io::Result<()> { - self.serialize_end("]") - } - - #[inline] - fn serialize_struct_start(&mut self, _name: &str, _len: usize) -> io::Result<()> { - self.first = true; - self.wr.write_all(b"{") - } - - #[inline] - fn serialize_struct_elt< - T: ser::Serialize, io::Error> - >(&mut self, name: &str, value: &T) -> io::Result<()> { - try!(self.serialize_sep()); - try!(self.serialize_str(name)); - try!(self.wr.write_all(b": ")); - value.serialize(self) - } - - #[inline] - fn serialize_struct_end(&mut self) -> io::Result<()> { - self.serialize_end("}") - } - - #[inline] - fn serialize_enum_start(&mut self, _name: &str, variant: &str, _len: usize) -> io::Result<()> { - self.first = true; - try!(self.wr.write_all(b"{")); - try!(self.serialize_sep()); - try!(self.serialize_str(variant)); - self.first = true; - self.wr.write_all(b": [") - } - - #[inline] - fn serialize_enum_elt< - T: ser::Serialize, io::Error> - >(&mut self, value: &T) -> io::Result<()> { - try!(self.serialize_sep()); - value.serialize(self) - } - - #[inline] - fn serialize_enum_end(&mut self) -> io::Result<()> { - try!(self.serialize_tuple_end()); - self.serialize_struct_end() - } - - #[inline] - fn serialize_option< - T: ser::Serialize, io::Error> - >(&mut self, v: &Option) -> io::Result<()> { - match *v { - Some(ref v) => { - v.serialize(self) +impl<'a, W> Visitor<'a, W> where W: io::Write, { + fn serialize_sep(&mut self, first: bool) -> io::Result<()> { + match self.format { + Format::Compact => { + if first { + Ok(()) + } else { + self.writer.write_all(b",") + } } - None => { - self.serialize_null() + Format::Pretty => { + if first { + self.current_indent += self.indent; + try!(self.writer.write_all(b"\n")); + } else { + try!(self.writer.write_all(b",\n")); + } + + spaces(&mut self.writer, self.current_indent) } } } - #[inline] - fn serialize_seq< - T: ser::Serialize, io::Error>, - Iter: Iterator - >(&mut self, iter: Iter) -> io::Result<()> { - try!(self.wr.write_all(b"[")); - - self.first = true; - for elt in iter { - try!(self.serialize_sep()); - try!(elt.serialize(self)); + fn serialize_colon(&mut self) -> io::Result<()> { + match self.format { + Format::Compact => self.writer.write_all(b":"), + Format::Pretty => self.writer.write_all(b": "), } - - self.serialize_end("]") } - #[inline] - fn serialize_map< - K: ser::Serialize, io::Error>, - V: ser::Serialize, io::Error>, - Iter: Iterator - >(&mut self, iter: Iter) -> io::Result<()> { - try!(self.wr.write_all(b"{")); - - self.first = true; - for (key, value) in iter { - try!(self.serialize_sep()); - try!(key.serialize(self)); - try!(self.wr.write_all(b": ")); - try!(value.serialize(self)); + fn serialize_end(&mut self, current_indent: usize, s: &[u8]) -> io::Result<()> { + if self.format == Format::Pretty && current_indent != self.current_indent { + self.current_indent -= self.indent; + try!(self.writer.write(b"\n")); + try!(spaces(&mut self.writer, self.current_indent)); } - self.serialize_end("}") + self.writer.write_all(s) } } -fn escape_bytes(wr: &mut W, bytes: &[u8]) -> io::Result<()> +impl<'a, W> ser::Visitor for Visitor<'a, W> where W: io::Write, { + type Value = (); + type Error = io::Error; + + #[inline] + fn visit_bool(&mut self, value: bool) -> io::Result<()> { + if value { + self.writer.write_all(b"true") + } else { + self.writer.write_all(b"false") + } + } + + #[inline] + fn visit_isize(&mut self, value: isize) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_i8(&mut self, value: i8) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_i16(&mut self, value: i16) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_i32(&mut self, value: i32) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_i64(&mut self, value: i64) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_usize(&mut self, value: usize) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_u8(&mut self, value: u8) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_u16(&mut self, value: u16) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_u32(&mut self, value: u32) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_u64(&mut self, value: u64) -> io::Result<()> { + write!(self.writer, "{}", value) + } + + #[inline] + fn visit_f32(&mut self, value: f32) -> io::Result<()> { + fmt_f32_or_null(self.writer, value) + } + + #[inline] + fn visit_f64(&mut self, value: f64) -> io::Result<()> { + fmt_f64_or_null(self.writer, value) + } + + #[inline] + fn visit_char(&mut self, value: char) -> io::Result<()> { + escape_char(self.writer, value) + } + + #[inline] + fn visit_str(&mut self, value: &str) -> io::Result<()> { + escape_str(self.writer, value) + } + + #[inline] + fn visit_none(&mut self) -> io::Result<()> { + self.visit_unit() + } + + #[inline] + fn visit_some(&mut self, value: V) -> io::Result<()> + where V: ser::Serialize + { + value.visit(self) + } + + #[inline] + fn visit_unit(&mut self) -> io::Result<()> { + self.writer.write_all(b"null") + } + + #[inline] + fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> io::Result<()> { + let current_indent = self.current_indent; + + try!(self.writer.write_all(b"{")); + try!(self.serialize_sep(true)); + try!(self.visit_str(variant)); + try!(self.serialize_colon()); + try!(self.writer.write_all(b"[]")); + self.serialize_end(current_indent, b"}") + } + + #[inline] + fn visit_seq(&mut self, mut visitor: V) -> io::Result<()> + where V: ser::SeqVisitor, + { + let current_indent = self.current_indent; + + try!(self.writer.write_all(b"[")); + + while let Some(()) = try!(visitor.visit(self)) { } + + self.serialize_end(current_indent, b"]") + } + + #[inline] + fn visit_enum_seq(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()> + where V: ser::SeqVisitor, + { + let current_indent = self.current_indent; + + try!(self.writer.write_all(b"{")); + try!(self.serialize_sep(true)); + try!(self.visit_str(variant)); + try!(self.serialize_colon()); + try!(self.visit_seq(visitor)); + self.serialize_end(current_indent, b"}") + } + + #[inline] + fn visit_seq_elt(&mut self, first: bool, value: T) -> io::Result<()> + where T: ser::Serialize, + { + try!(self.serialize_sep(first)); + + value.visit(self) + } + + #[inline] + fn visit_map(&mut self, mut visitor: V) -> io::Result<()> + where V: ser::MapVisitor, + { + let current_indent = self.current_indent; + + try!(self.writer.write_all(b"{")); + + while let Some(()) = try!(visitor.visit(self)) { } + + self.serialize_end(current_indent, b"}") + } + + #[inline] + fn visit_enum_map(&mut self, _name: &str, variant: &str, visitor: V) -> io::Result<()> + where V: ser::MapVisitor, + { + let current_indent = self.current_indent; + + try!(self.writer.write_all(b"{")); + try!(self.serialize_sep(true)); + try!(self.visit_str(variant)); + try!(self.serialize_colon()); + try!(self.visit_map(visitor)); + self.serialize_end(current_indent, b"}") + } + + #[inline] + fn visit_map_elt(&mut self, first: bool, key: K, value: V) -> io::Result<()> + where K: ser::Serialize, + V: ser::Serialize, + { + try!(self.serialize_sep(first)); + try!(key.visit(self)); + try!(self.serialize_colon()); + value.visit(self) + } +} + +#[inline] +pub fn escape_bytes(wr: &mut W, bytes: &[u8]) -> io::Result<()> where W: io::Write { try!(wr.write_all(b"\"")); @@ -524,15 +336,18 @@ fn escape_bytes(wr: &mut W, bytes: &[u8]) -> io::Result<()> try!(wr.write_all(&bytes[start..])); } - wr.write_all(b"\"") + try!(wr.write_all(b"\"")); + Ok(()) } +#[inline] pub fn escape_str(wr: &mut W, value: &str) -> io::Result<()> where W: io::Write { escape_bytes(wr, value.as_bytes()) } +#[inline] fn escape_char(wr: &mut W, value: char) -> io::Result<()> where W: io::Write { @@ -559,9 +374,75 @@ fn fmt_f64_or_null(wr: &mut W, value: f64) -> io::Result<()> } } -fn spaces(wr: &mut W, mut n: usize) -> io::Result<()> { +/// Encode the specified struct into a json `[u8]` writer. +#[inline] +pub fn to_writer(writer: &mut W, value: &T) -> io::Result<()> + where W: io::Write, + T: ser::Serialize, +{ + let mut ser = Serializer::new(writer); + try!(ser::Serializer::visit(&mut ser, value)); + Ok(()) +} + +/// Encode the specified struct into a json `[u8]` writer. +#[inline] +pub fn to_writer_pretty(writer: &mut W, value: &T) -> io::Result<()> + where W: io::Write, + T: ser::Serialize, +{ + let mut ser = Serializer::new_pretty(writer); + try!(ser::Serializer::visit(&mut ser, value)); + Ok(()) +} + +/// Encode the specified struct into a json `[u8]` buffer. +#[inline] +pub fn to_vec(value: &T) -> Vec + where T: ser::Serialize, +{ + // We are writing to a Vec, which doesn't fail. So we can ignore + // the error. + let mut writer = Vec::with_capacity(128); + to_writer(&mut writer, value).unwrap(); + writer +} + +/// Encode the specified struct into a json `[u8]` buffer. +#[inline] +pub fn to_vec_pretty(value: &T) -> Vec + where T: ser::Serialize, +{ + // We are writing to a Vec, which doesn't fail. So we can ignore + // the error. + let mut writer = Vec::with_capacity(128); + to_writer_pretty(&mut writer, value).unwrap(); + writer +} + +/// Encode the specified struct into a json `String` buffer. +#[inline] +pub fn to_string(value: &T) -> Result + where T: ser::Serialize +{ + let vec = to_vec(value); + String::from_utf8(vec) +} + +/// Encode the specified struct into a json `String` buffer. +#[inline] +pub fn to_string_pretty(value: &T) -> Result + where T: ser::Serialize +{ + let vec = to_vec_pretty(value); + String::from_utf8(vec) +} + +fn spaces(wr: &mut W, mut n: usize) -> io::Result<()> + where W: io::Write, +{ const LEN: usize = 16; - const BUF: &'static [u8; LEN] = &[b' '; LEN]; + const BUF: &'static [u8; LEN] = &[b' '; 16]; while n >= LEN { try!(wr.write_all(BUF)); @@ -574,63 +455,3 @@ fn spaces(wr: &mut W, mut n: usize) -> io::Result<()> { Ok(()) } } - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_writer(writer: W, value: &T) -> io::Result - where W: io::Write, - T: ser::Serialize, io::Error> -{ - let mut serializer = Serializer::new(writer); - try!(value.serialize(&mut serializer)); - Ok(serializer.unwrap()) -} - -/// Encode the specified struct into a json `[u8]` buffer. -#[inline] -pub fn to_vec(value: &T) -> Vec - where T: ser::Serialize>, io::Error> -{ - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let writer = Vec::with_capacity(128); - to_writer(writer, value).unwrap() -} - -/// Encode the specified struct into a json `String` buffer. -#[inline] -pub fn to_string(value: &T) -> Result - where T: ser::Serialize>, io::Error> -{ - let vec = to_vec(value); - String::from_utf8(vec) -} - -/// Encode the specified struct into a json `[u8]` writer. -#[inline] -pub fn to_pretty_writer< - W: io::Write, - T: ser::Serialize, io::Error> ->(writer: W, value: &T) -> io::Result { - let mut serializer = PrettySerializer::new(writer); - try!(value.serialize(&mut serializer)); - Ok(serializer.unwrap()) -} - -/// Encode the specified struct into a json `[u8]` buffer. -pub fn to_pretty_vec< - T: ser::Serialize>, io::Error> ->(value: &T) -> Vec { - // We are writing to a Vec, which doesn't fail. So we can ignore - // the error. - let writer = Vec::with_capacity(128); - to_pretty_writer(writer, value).unwrap() -} - -/// Encode the specified struct into a json `String` buffer. -pub fn to_pretty_string< - T: ser::Serialize>, io::Error> ->(value: &T) -> Result { - let buf = to_pretty_vec(value); - String::from_utf8(buf) -} diff --git a/src/json/value.rs b/src/json/value.rs index ef540787..b7698d96 100644 --- a/src/json/value.rs +++ b/src/json/value.rs @@ -1,217 +1,113 @@ -use std::collections::{HashMap, BTreeMap, btree_map}; +use std::collections::{BTreeMap, btree_map}; use std::fmt; -use std::io::{self, WriteExt}; +use std::io; use std::str; -use std::string::ToString; use std::vec; -use de::{self, Token, TokenKind}; -use ser::Serialize; +use de; use ser; +use super::error::Error; -use super::ser::{Serializer, PrettySerializer}; -use super::error::{Error, ErrorCode}; - -/// Represents a JSON value -#[derive(Clone, PartialEq, PartialOrd)] +#[derive(Clone, PartialEq)] pub enum Value { Null, - Boolean(bool), - Integer(i64), - Floating(f64), + Bool(bool), + I64(i64), + F64(f64), String(String), Array(Vec), Object(BTreeMap), } -impl Value { - /// Serializes a json value into an io::writer. Uses a single line. - pub fn to_writer(&self, wr: W) -> io::Result<()> { - let mut serializer = Serializer::new(wr); - self.serialize(&mut serializer) - } - - /// Serializes a json value into an io::writer. - /// Pretty-prints in a more readable format. - pub fn to_pretty_writer(&self, wr: W) -> io::Result<()> { - let mut serializer = PrettySerializer::new(wr); - self.serialize(&mut serializer) - } - - /// Serializes a json value into a string - pub fn to_pretty_string(&self) -> String { - let mut wr = Vec::new(); - self.to_pretty_writer(wr.by_ref()).unwrap(); - str::from_utf8(&wr).unwrap().to_string() - } - - /// If the Json value is an Object, returns the value associated with the provided key. - /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &String) -> Option<&'a Value>{ - match self { - &Value::Object(ref map) => map.get(key), - _ => None - } - } - - /// Attempts to get a nested Json Object for each key in `keys`. - /// If any key is found not to exist, find_path will return None. - /// Otherwise, it will return the Json value associated with the final key. - pub fn find_path<'a>(&'a self, keys: &[&String]) -> Option<&'a Value>{ - let mut target = self; - for key in keys { - match target.find(*key) { - Some(t) => { target = t; }, - None => return None - } - } - Some(target) - } - - /// If the Json value is an Object, performs a depth-first search until - /// a value associated with the provided key is found. If no value is found - /// or the Json value is not an Object, returns None. - pub fn search<'a>(&'a self, key: &String) -> Option<&'a Value> { - match self { - &Value::Object(ref map) => { - match map.get(key) { - Some(json_value) => Some(json_value), - None => { - let mut value : Option<&'a Value> = None; - for (_, v) in map { - value = v.search(key); - if value.is_some() { - break; - } - } - value - } - } - }, - _ => None - } - } - - /// Returns true if the Json value is an Object. Returns false otherwise. - pub fn is_object<'a>(&'a self) -> bool { - self.as_object().is_some() - } - - /// If the Json value is an Object, returns the associated TreeMap. - /// Returns None otherwise. - pub fn as_object<'a>(&'a self) -> Option<&'a BTreeMap> { +impl ser::Serialize for Value { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: ser::Visitor, + { match *self { - Value::Object(ref map) => Some(map), - _ => None - } - } - - /// Returns true if the Json value is a Array. Returns false otherwise. - pub fn is_array<'a>(&'a self) -> bool { - self.as_array().is_some() - } - - /// If the Json value is a Array, returns the associated vector. - /// Returns None otherwise. - pub fn as_array<'a>(&'a self) -> Option<&'a Vec> { - match *self { - Value::Array(ref array) => Some(array), - _ => None - } - } - - /// Returns true if the Json value is a String. Returns false otherwise. - pub fn is_string<'a>(&'a self) -> bool { - self.as_string().is_some() - } - - /// If the Json value is a String, returns the associated str. - /// Returns None otherwise. - pub fn as_string<'a>(&'a self) -> Option<&'a str> { - match *self { - Value::String(ref s) => Some(&s), - _ => None - } - } - - /// Returns true if the Json value is a i64 or f64. Returns false otherwise. - pub fn is_number(&self) -> bool { - match *self { - Value::Integer(_) | Value::Floating(_) => true, - _ => false, - } - } - - /// Returns true if the Json value is a i64. Returns false otherwise. - pub fn is_i64(&self) -> bool { - match *self { - Value::Integer(_) => true, - _ => false, - } - } - - /// Returns true if the Json value is a f64. Returns false otherwise. - pub fn is_f64(&self) -> bool { - match *self { - Value::Floating(_) => true, - _ => false, - } - } - - /// If the Json value is a i64, returns the associated i64. - /// Returns None otherwise. - pub fn as_i64(&self) -> Option { - match *self { - Value::Integer(n) => Some(n), - Value::Floating(n) => Some(n as i64), - _ => None - } - } - - /// If the Json value is a f64, returns the associated f64. - /// Returns None otherwise. - pub fn as_f64(&self) -> Option { - match *self { - Value::Integer(n) => Some(n as f64), - Value::Floating(n) => Some(n), - _ => None - } - } - - /// Returns true if the Json value is a Boolean. Returns false otherwise. - pub fn is_boolean(&self) -> bool { - self.as_boolean().is_some() - } - - /// If the Json value is a Boolean, returns the associated bool. - /// Returns None otherwise. - pub fn as_boolean(&self) -> Option { - match *self { - Value::Boolean(b) => Some(b), - _ => None - } - } - - /// Returns true if the Json value is a Null. Returns false otherwise. - pub fn is_null(&self) -> bool { - self.as_null().is_some() - } - - /// If the Json value is a Null, returns (). - /// Returns None otherwise. - pub fn as_null(&self) -> Option<()> { - match *self { - Value::Null => Some(()), - _ => None + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(v), + Value::I64(v) => visitor.visit_i64(v), + Value::F64(v) => visitor.visit_f64(v), + Value::String(ref v) => visitor.visit_str(&v), + Value::Array(ref v) => v.visit(visitor), + Value::Object(ref v) => v.visit(visitor), } } } -impl ToString for Value { - fn to_string(&self) -> String { - let mut wr = Vec::new(); - self.to_writer(wr.by_ref()).unwrap(); - str::from_utf8(&wr).unwrap().to_string() +impl de::Deserialize for Value { + #[inline] + fn deserialize(deserializer: &mut D) -> Result + where D: de::Deserializer, + { + struct ValueVisitor; + + impl de::Visitor for ValueVisitor { + type Value = Value; + + #[inline] + fn visit_bool(&mut self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn visit_i64(&mut self, value: i64) -> Result { + Ok(Value::I64(value)) + } + + #[inline] + fn visit_f64(&mut self, value: f64) -> Result { + Ok(Value::F64(value)) + } + + #[inline] + fn visit_str(&mut self, value: &str) -> Result + where E: de::Error, + { + self.visit_string(value.to_string()) + } + + #[inline] + fn visit_string(&mut self, value: String) -> Result { + Ok(Value::String(value)) + } + + #[inline] + fn visit_none(&mut self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_some(&mut self, deserializer: &mut D) -> Result + where D: de::Deserializer, + { + de::Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(&mut self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_seq(&mut self, visitor: V) -> Result + where V: de::SeqVisitor, + { + let values = try!(de::VecVisitor::new().visit_seq(visitor)); + Ok(Value::Array(values)) + } + + #[inline] + fn visit_map(&mut self, visitor: V) -> Result + where V: de::MapVisitor, + { + let values = try!(de::BTreeMapVisitor::new().visit_map(visitor)); + Ok(Value::Object(values)) + } + } + + deserializer.visit(ValueVisitor) } } @@ -235,448 +131,474 @@ impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { impl fmt::Debug for Value { /// Serializes a json value into a string fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let wr = WriterFormatter { inner: f }; - self.to_writer(wr).map_err(|_| fmt::Error) - } -} - -impl, E> ser::Serialize for Value { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - match *self { - Value::Null => { - ().serialize(s) - } - Value::Boolean(v) => { - v.serialize(s) - } - Value::Integer(v) => { - v.serialize(s) - } - Value::Floating(v) => { - v.serialize(s) - } - Value::String(ref v) => { - v.serialize(s) - } - Value::Array(ref v) => { - v.serialize(s) - } - Value::Object(ref v) => { - v.serialize(s) - } - } - } -} - -impl, E> de::Deserialize for Value { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - match token { - Token::Null => Ok(Value::Null), - Token::Bool(x) => Ok(Value::Boolean(x)), - Token::Isize(x) => Ok(Value::Integer(x as i64)), - Token::I8(x) => Ok(Value::Integer(x as i64)), - Token::I16(x) => Ok(Value::Integer(x as i64)), - Token::I32(x) => Ok(Value::Integer(x as i64)), - Token::I64(x) => Ok(Value::Integer(x)), - Token::Usize(x) => Ok(Value::Integer(x as i64)), - Token::U8(x) => Ok(Value::Integer(x as i64)), - Token::U16(x) => Ok(Value::Integer(x as i64)), - Token::U32(x) => Ok(Value::Integer(x as i64)), - Token::U64(x) => Ok(Value::Integer(x as i64)), - Token::F32(x) => Ok(Value::Floating(x as f64)), - Token::F64(x) => Ok(Value::Floating(x)), - Token::Char(x) => Ok(Value::String(x.to_string())), - Token::Str(x) => Ok(Value::String(x.to_string())), - Token::String(x) => Ok(Value::String(x)), - Token::Option(false) => Ok(Value::Null), - Token::Option(true) => de::Deserialize::deserialize(d), - Token::TupleStart(_) | Token::SeqStart(_) => { - let array = try!(de::Deserialize::deserialize_token(d, token)); - Ok(Value::Array(array)) - } - Token::StructStart(_, _) | Token::MapStart(_) => { - let object = try!(de::Deserialize::deserialize_token(d, token)); - Ok(Value::Object(object)) - } - Token::EnumStart(_, name, len) => { - let token = Token::SeqStart(len); - let fields: Vec = try!(de::Deserialize::deserialize_token(d, token)); - let mut object = BTreeMap::new(); - object.insert(name.to_string(), Value::Array(fields)); - Ok(Value::Object(object)) - } - Token::End => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::EndKind, - ]; - Err(d.syntax_error(Token::End, EXPECTED_TOKENS)) - } - } + let mut wr = WriterFormatter { inner: f }; + super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) } } +#[derive(Debug)] enum State { Value(Value), - Array(vec::IntoIter), - Object(btree_map::IntoIter), - End, + Array(Vec), + Object(BTreeMap), +} + +pub struct Serializer { + state: Vec, +} + +impl Serializer { + pub fn new() -> Serializer { + Serializer { + state: Vec::with_capacity(4), + } + } + + pub fn unwrap(mut self) -> Value { + match self.state.pop().unwrap() { + State::Value(value) => value, + state => panic!("expected value, found {:?}", state), + } + } +} + +impl ser::Serializer for Serializer { + type Value = (); + type Error = (); + + #[inline] + fn visit(&mut self, value: &T) -> Result<(), ()> + where T: ser::Serialize, + { + try!(value.visit(self)); + Ok(()) + } +} + +impl ser::Visitor for Serializer { + type Value = (); + type Error = (); + + #[inline] + fn visit_bool(&mut self, value: bool) -> Result<(), ()> { + self.state.push(State::Value(Value::Bool(value))); + Ok(()) + } + + #[inline] + fn visit_i64(&mut self, value: i64) -> Result<(), ()> { + self.state.push(State::Value(Value::I64(value))); + Ok(()) + } + + #[inline] + fn visit_u64(&mut self, value: u64) -> Result<(), ()> { + self.state.push(State::Value(Value::I64(value as i64))); + Ok(()) + } + + #[inline] + fn visit_f64(&mut self, value: f64) -> Result<(), ()> { + self.state.push(State::Value(Value::F64(value as f64))); + Ok(()) + } + + #[inline] + fn visit_char(&mut self, value: char) -> Result<(), ()> { + self.state.push(State::Value(Value::String(value.to_string()))); + Ok(()) + } + + #[inline] + fn visit_str(&mut self, value: &str) -> Result<(), ()> { + self.state.push(State::Value(Value::String(value.to_string()))); + Ok(()) + } + + #[inline] + fn visit_none(&mut self) -> Result<(), ()> { + self.visit_unit() + } + + #[inline] + fn visit_some(&mut self, value: V) -> Result<(), ()> + where V: ser::Serialize, + { + value.visit(self) + } + + #[inline] + fn visit_unit(&mut self) -> Result<(), ()> { + self.state.push(State::Value(Value::Null)); + Ok(()) + } + + #[inline] + fn visit_enum_unit(&mut self, _name: &str, variant: &str) -> Result<(), ()> { + let mut values = BTreeMap::new(); + values.insert(variant.to_string(), Value::Array(vec![])); + + self.state.push(State::Value(Value::Object(values))); + + Ok(()) + } + + #[inline] + fn visit_seq(&mut self, mut visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor, + { + let len = match visitor.size_hint() { + (_, Some(len)) => len, + (len, None) => len, + }; + + let values = Vec::with_capacity(len); + + self.state.push(State::Array(values)); + + while let Some(()) = try!(visitor.visit(self)) { } + + let values = match self.state.pop().unwrap() { + State::Array(values) => values, + state => panic!("Expected array, found {:?}", state), + }; + + self.state.push(State::Value(Value::Array(values))); + + Ok(()) + } + + #[inline] + fn visit_enum_seq(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()> + where V: ser::SeqVisitor, + { + try!(self.visit_seq(visitor)); + + let value = match self.state.pop().unwrap() { + State::Value(value) => value, + state => panic!("expected value, found {:?}", state), + }; + + let mut object = BTreeMap::new(); + + object.insert(variant.to_string(), value); + + self.state.push(State::Value(Value::Object(object))); + + Ok(()) + } + + #[inline] + fn visit_seq_elt(&mut self, _first: bool, value: T) -> Result<(), ()> + where T: ser::Serialize, + { + try!(value.visit(self)); + + let value = match self.state.pop().unwrap() { + State::Value(value) => value, + state => panic!("expected value, found {:?}", state), + }; + + match *self.state.last_mut().unwrap() { + State::Array(ref mut values) => { values.push(value); } + ref state => panic!("expected array, found {:?}", state), + } + + Ok(()) + } + + #[inline] + fn visit_map(&mut self, mut visitor: V) -> Result<(), ()> + where V: ser::MapVisitor, + { + let values = BTreeMap::new(); + + self.state.push(State::Object(values)); + + while let Some(()) = try!(visitor.visit(self)) { } + + let values = match self.state.pop().unwrap() { + State::Object(values) => values, + state => panic!("expected object, found {:?}", state), + }; + + self.state.push(State::Value(Value::Object(values))); + + Ok(()) + } + + #[inline] + fn visit_enum_map(&mut self, _name: &str, variant: &str, visitor: V) -> Result<(), ()> + where V: ser::MapVisitor, + { + try!(self.visit_map(visitor)); + + let value = match self.state.pop().unwrap() { + State::Value(value) => value, + state => panic!("expected value, found {:?}", state), + }; + + let mut object = BTreeMap::new(); + + object.insert(variant.to_string(), value); + + self.state.push(State::Value(Value::Object(object))); + + Ok(()) + } + + #[inline] + fn visit_map_elt(&mut self, _first: bool, key: K, value: V) -> Result<(), ()> + where K: ser::Serialize, + V: ser::Serialize, + { + try!(key.visit(self)); + + let key = match self.state.pop().unwrap() { + State::Value(Value::String(value)) => value, + state => panic!("expected key, found {:?}", state), + }; + + try!(value.visit(self)); + + let value = match self.state.pop().unwrap() { + State::Value(value) => value, + state => panic!("expected value, found {:?}", state), + }; + + match *self.state.last_mut().unwrap() { + State::Object(ref mut values) => { values.insert(key, value); } + ref state => panic!("expected object, found {:?}", state), + } + + Ok(()) + } } pub struct Deserializer { - stack: Vec, + value: Option, } impl Deserializer { /// Creates a new deserializer instance for deserializing the specified JSON value. - pub fn new(json: Value) -> Deserializer { + pub fn new(value: Value) -> Deserializer { Deserializer { - stack: vec!(State::Value(json)), + value: Some(value), } } } -impl Iterator for Deserializer { - type Item = Result; +impl de::Deserializer for Deserializer { + type Error = Error; #[inline] - fn next(&mut self) -> Option> { - loop { - match self.stack.pop() { - Some(State::Value(value)) => { - let token = match value { - Value::Null => Token::Null, - Value::Boolean(x) => Token::Bool(x), - Value::Integer(x) => Token::I64(x), - Value::Floating(x) => Token::F64(x), - Value::String(x) => Token::String(x), - Value::Array(x) => { - let len = x.len(); - self.stack.push(State::Array(x.into_iter())); - Token::SeqStart(len) - } - Value::Object(x) => { - let len = x.len(); - self.stack.push(State::Object(x.into_iter())); - Token::MapStart(len) - } - }; - - return Some(Ok(token)); - } - Some(State::Array(mut iter)) => { - match iter.next() { - Some(value) => { - self.stack.push(State::Array(iter)); - self.stack.push(State::Value(value)); - // loop around. - } - None => { - return Some(Ok(Token::End)); - } - } - } - Some(State::Object(mut iter)) => { - match iter.next() { - Some((key, value)) => { - self.stack.push(State::Object(iter)); - self.stack.push(State::Value(value)); - return Some(Ok(Token::String(key))); - } - None => { - return Some(Ok(Token::End)); - } - } - } - Some(State::End) => { - return Some(Ok(Token::End)); - } - None => { return None; } - } - } - } -} - -impl de::Deserializer for Deserializer { - fn end_of_stream_error(&mut self) -> Error { - Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 0, 0) - } - - fn syntax_error(&mut self, - token: Token, - expected: &'static [TokenKind]) -> Error { - Error::SyntaxError(ErrorCode::ExpectedTokens(token, expected), 0, 0) - } - - fn unexpected_name_error(&mut self, token: Token) -> Error { - Error::SyntaxError(ErrorCode::UnexpectedName(token), 0, 0) - } - - fn conversion_error(&mut self, token: Token) -> Error { - Error::SyntaxError(ErrorCode::ConversionError(token), 0, 0) - } - - #[inline] - fn missing_field< - T: de::Deserialize - >(&mut self, _field: &'static str) -> Result { - // JSON can represent `null` values as a missing value, so this isn't - // necessarily an error. - de::Deserialize::deserialize_token(self, Token::Null) - } - - // Special case treating options as a nullable value. - #[inline] - fn expect_option< - U: de::Deserialize - >(&mut self, token: Token) -> Result, Error> { - match token { - Token::Null => Ok(None), - token => { - let value: U = try!(de::Deserialize::deserialize_token(self, token)); - Ok(Some(value)) - } - } - } - - // Special case treating enums as a String or a `{"variant": "...", "fields": [...]}`. - #[inline] - fn expect_enum_start(&mut self, - token: Token, - _name: &str, - variants: &[&str]) -> Result { - let variant = match token { - Token::MapStart(_) => { - let state = match self.stack.pop() { - Some(state) => state, - None => { panic!("state machine error, state stack empty"); } - }; - - let mut iter = match state { - State::Object(iter) => iter, - _ => { panic!("state machine error, expected an object"); } - }; - - let (variant, fields) = match iter.next() { - Some((variant, Value::Array(fields))) => (variant, fields), - Some((key, value)) => { - return Err( - Error::ExpectedError( - "Array".to_string(), - format!("{:?} => {:?}", key, value) - ) - ); - } - None => { - return Err(Error::MissingFieldError("".to_string())); - } - }; - - // Error out if there are other fields in the enum. - match iter.next() { - Some((key, value)) => { - return Err( - Error::ExpectedError( - "None".to_string(), - format!("{:?} => {:?}", key, value) - ) - ); - } - None => { } - } - - self.stack.push(State::End); - - for field in fields.into_iter().rev() { - self.stack.push(State::Value(field)); - } - - variant - } - token => { - return Err( - Error::ExpectedError( - "String or Object".to_string(), - format!("{:?}", token) - ) - ); - } + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + let value = match self.value.take() { + Some(value) => value, + None => { return Err(de::Error::end_of_stream_error()); } }; - match variants.iter().position(|v| *v == &variant[]) { - Some(idx) => Ok(idx), - None => Err(Error::UnknownVariantError(variant)), + match value { + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(v), + Value::I64(v) => visitor.visit_i64(v), + Value::F64(v) => visitor.visit_f64(v), + Value::String(v) => visitor.visit_string(v), + Value::Array(v) => { + let len = v.len(); + visitor.visit_seq(SeqDeserializer { + de: self, + iter: v.into_iter(), + len: len, + }) + } + Value::Object(v) => { + let len = v.len(); + visitor.visit_map(MapDeserializer { + de: self, + iter: v.into_iter(), + value: None, + len: len, + }) + } } } #[inline] - fn expect_struct_start(&mut self, token: Token, _name: &str) -> Result<(), Error> { - match token { - Token::MapStart(_) => Ok(()), - _ => { - static EXPECTED_TOKENS: &'static [TokenKind] = &[ - TokenKind::MapStartKind - ]; - Err(self.syntax_error(token, EXPECTED_TOKENS)) + fn visit_option(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + match self.value { + Some(Value::Null) => visitor.visit_none(), + Some(_) => visitor.visit_some(self), + None => Err(de::Error::end_of_stream_error()), + } + } + + #[inline] + fn visit_enum(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + let value = match self.value.take() { + Some(Value::Object(value)) => value, + Some(_) => { return Err(de::Error::syntax_error()); } + None => { return Err(de::Error::end_of_stream_error()); } + }; + + let mut iter = value.into_iter(); + + let value = match iter.next() { + Some((variant, Value::Array(fields))) => { + let len = fields.len(); + try!(visitor.visit_variant(&variant, SeqDeserializer { + de: self, + iter: fields.into_iter(), + len: len, + })) } - } - } -} - -/// Decodes a json value from a `Value`. -pub fn from_json< - T: de::Deserialize ->(json: Value) -> Result { - let mut d = Deserializer::new(json); - de::Deserialize::deserialize(&mut d) -} - -/// A trait for converting values to JSON -pub trait ToJson { - /// Converts the value of `self` to an instance of JSON - fn to_json(&self) -> Value; -} - -impl ToJson for Value { - fn to_json(&self) -> Value { self.clone() } -} - -impl ToJson for isize { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for i8 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for i16 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for i32 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for i64 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for usize { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for u8 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for u16 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for u32 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for u64 { - fn to_json(&self) -> Value { Value::Integer(*self as i64) } -} - -impl ToJson for f32 { - fn to_json(&self) -> Value { Value::Floating(*self as f64) } -} - -impl ToJson for f64 { - fn to_json(&self) -> Value { Value::Floating(*self) } -} - -impl ToJson for bool { - fn to_json(&self) -> Value { Value::Boolean(*self) } -} - -impl<'a> ToJson for &'a str { - fn to_json(&self) -> Value { Value::String(self.to_string()) } -} - -impl ToJson for String { - fn to_json(&self) -> Value { Value::String(self.clone()) } -} - -macro_rules! peel_to_json_tuple { - ($name:ident, $($other:ident,)*) => ( impl_to_json_tuple!($($other,)*); ) -} - -macro_rules! impl_to_json_tuple { - () => { - impl<> ToJson for () { - #[inline] - fn to_json(&self) -> Value { - Value::Null + Some((variant, Value::Object(fields))) => { + let len = fields.len(); + try!(visitor.visit_variant(&variant, MapDeserializer { + de: self, + iter: fields.into_iter(), + value: None, + len: len, + })) } + Some(_) => { return Err(de::Error::syntax_error()); } + None => { return Err(de::Error::syntax_error()); } + }; + + match iter.next() { + Some(_) => Err(de::Error::syntax_error()), + None => Ok(value) } - }; - ( $($name:ident,)+ ) => { - impl<$($name: ToJson),*> ToJson for ($($name,)*) { - #[inline] - #[allow(non_snake_case)] - fn to_json(&self) -> Value { - // FIXME: how can we count macro args? - let mut len = 0; - $({ let $name = 1; len += $name; })*; + } +} - let ($(ref $name,)*) = *self; +struct SeqDeserializer<'a> { + de: &'a mut Deserializer, + iter: vec::IntoIter, + len: usize, +} - let mut array = Vec::with_capacity(len); - $( - array.push($name.to_json()); - )* +impl<'a> de::SeqVisitor for SeqDeserializer<'a> { + type Error = Error; - Value::Array(array) + fn visit(&mut self) -> Result, Error> + where T: de::Deserialize + { + match self.iter.next() { + Some(value) => { + self.len -= 1; + self.de.value = Some(value); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) } - } - peel_to_json_tuple!($($name,)*); - } -} - -impl_to_json_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } - -impl ToJson for Vec { - fn to_json(&self) -> Value { - Value::Array(self.iter().map(|elt| elt.to_json()).collect()) - } -} - -impl ToJson for BTreeMap { - fn to_json(&self) -> Value { - let mut d = BTreeMap::new(); - for (key, value) in self { - d.insert(key.clone(), value.to_json()); - } - Value::Object(d) - } -} - -impl ToJson for HashMap { - fn to_json(&self) -> Value { - let mut d = BTreeMap::new(); - for (key, value) in self { - d.insert(key.clone(), value.to_json()); - } - Value::Object(d) - } -} - -impl ToJson for Option { - fn to_json(&self) -> Value { - match *self { - None => Value::Null, - Some(ref value) => value.to_json() + None => Ok(None), } } -} -impl<'a, T: ToJson> ToJson for &'a T { - fn to_json(&self) -> Value { - (*self).to_json() + fn end(&mut self) -> Result<(), Error> { + if self.len == 0 { + Ok(()) + } else { + Err(de::Error::end_of_stream_error()) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) } } + +impl<'a> de::EnumVisitor for SeqDeserializer<'a> { + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + if self.len == 0 { + Ok(()) + } else { + Err(de::Error::syntax_error()) + } + } + + fn visit_seq(&mut self, mut visitor: V) -> Result + where V: de::EnumSeqVisitor, + { + visitor.visit(self) + } +} + +struct MapDeserializer<'a> { + de: &'a mut Deserializer, + iter: btree_map::IntoIter, + value: Option, + len: usize, +} + +impl<'a> de::MapVisitor for MapDeserializer<'a> { + type Error = Error; + + fn visit_key(&mut self) -> Result, Error> + where T: de::Deserialize + { + match self.iter.next() { + Some((key, value)) => { + self.len -= 1; + self.value = Some(value); + self.de.value = Some(Value::String(key)); + Ok(Some(try!(de::Deserialize::deserialize(self.de)))) + } + None => Ok(None), + } + } + + fn visit_value(&mut self) -> Result + where T: de::Deserialize + { + let value = self.value.take().unwrap(); + self.de.value = Some(value); + Ok(try!(de::Deserialize::deserialize(self.de))) + } + + fn end(&mut self) -> Result<(), Error> { + if self.len == 0 { + Ok(()) + } else { + Err(de::Error::end_of_stream_error()) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + +impl<'a> de::EnumVisitor for MapDeserializer<'a> { + type Error = Error; + + fn visit_map(&mut self, mut visitor: V) -> Result + where V: de::EnumMapVisitor, + { + visitor.visit(self) + } +} + +/// Shortcut function to encode a `T` into a JSON `Value` +pub fn to_value(value: &T) -> Value + where T: ser::Serialize +{ + let mut ser = Serializer::new(); + ser::Serializer::visit(&mut ser, value).ok().unwrap(); + ser.unwrap() +} + +/// Shortcut function to decode a JSON `Value` into a `T` +pub fn from_value(value: Value) -> Result + where T: de::Deserialize +{ + let mut de = Deserializer::new(value); + de::Deserialize::deserialize(&mut de) +} diff --git a/src/lib.rs b/src/lib.rs index fe023da9..102a272b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,17 +1,10 @@ -#![feature(collections, core, hash, io, std_misc, plugin, unicode)] -#![plugin(serde_macros)] +#![feature(core, io, path, std_misc, unicode)] extern crate unicode; -pub use de::{Deserializer, Deserialize}; -pub use ser::{Serializer, Serialize}; +pub use ser::{Serialize, Serializer}; +pub use de::{Deserialize, Deserializer, Error}; -pub mod de; pub mod ser; +pub mod de; pub mod json; - -// an inner module so we can use serde_macros. -mod serde { - pub use de; - pub use ser; -} diff --git a/src/ser.rs b/src/ser.rs index 43fa8035..2efb786a 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -1,315 +1,660 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet}; -use std::collections::hash_map::Hasher; +use std::collections::hash_state::HashState; +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::hash::Hash; +use std::path; use std::rc::Rc; +use std::str; use std::sync::Arc; -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -pub trait Serializer { - fn serialize_null(&mut self) -> Result<(), E>; - - fn serialize_bool(&mut self, v: bool) -> Result<(), E>; - - #[inline] - fn serialize_isize(&mut self, v: isize) -> Result<(), E> { - self.serialize_i64(v as i64) - } - - #[inline] - fn serialize_i8(&mut self, v: i8) -> Result<(), E> { - self.serialize_i64(v as i64) - } - - #[inline] - fn serialize_i16(&mut self, v: i16) -> Result<(), E> { - self.serialize_i64(v as i64) - } - - #[inline] - fn serialize_i32(&mut self, v: i32) -> Result<(), E> { - self.serialize_i64(v as i64) - } - - #[inline] - fn serialize_i64(&mut self, v: i64) -> Result<(), E>; - - #[inline] - fn serialize_usize(&mut self, v: usize) -> Result<(), E> { - self.serialize_u64(v as u64) - } - - #[inline] - fn serialize_u8(&mut self, v: u8) -> Result<(), E> { - self.serialize_u64(v as u64) - } - - #[inline] - fn serialize_u16(&mut self, v: u16) -> Result<(), E> { - self.serialize_u64(v as u64) - } - - #[inline] - fn serialize_u32(&mut self, v: u32) -> Result<(), E> { - self.serialize_u64(v as u64) - } - - #[inline] - fn serialize_u64(&mut self, v: u64) -> Result<(), E>; - - #[inline] - fn serialize_f32(&mut self, v: f32) -> Result<(), E> { - self.serialize_f64(v as f64) - } - - fn serialize_f64(&mut self, v: f64) -> Result<(), E>; - - fn serialize_char(&mut self, v: char) -> Result<(), E>; - - fn serialize_str(&mut self, v: &str) -> Result<(), E>; - - fn serialize_tuple_start(&mut self, len: usize) -> Result<(), E>; - fn serialize_tuple_elt< - T: Serialize - >(&mut self, v: &T) -> Result<(), E>; - fn serialize_tuple_end(&mut self) -> Result<(), E>; - - fn serialize_struct_start(&mut self, name: &str, len: usize) -> Result<(), E>; - fn serialize_struct_elt< - T: Serialize - >(&mut self, name: &str, v: &T) -> Result<(), E>; - fn serialize_struct_end(&mut self) -> Result<(), E>; - - fn serialize_enum_start(&mut self, name: &str, variant: &str, len: usize) -> Result<(), E>; - fn serialize_enum_elt< - T: Serialize - >(&mut self, v: &T) -> Result<(), E>; - fn serialize_enum_end(&mut self) -> Result<(), E>; - - fn serialize_option< - T: Serialize - >(&mut self, v: &Option) -> Result<(), E>; - - fn serialize_seq< - T: Serialize, - Iter: Iterator - >(&mut self, iter: Iter) -> Result<(), E>; - - fn serialize_map< - K: Serialize, - V: Serialize, - Iter: Iterator - >(&mut self, iter: Iter) -> Result<(), E>; +pub trait Serialize { + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor; } -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -pub trait Serialize, E> { - fn serialize(&self, s: &mut S) -> Result<(), E>; +pub trait Serializer { + type Value; + type Error; + + fn visit(&mut self, value: &T) -> Result + where T: Serialize; } -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_serialize { +pub trait Visitor { + type Value; + type Error; + + fn visit_bool(&mut self, v: bool) -> Result; + + #[inline] + fn visit_isize(&mut self, v: isize) -> Result { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i8(&mut self, v: i8) -> Result { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i16(&mut self, v: i16) -> Result { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i32(&mut self, v: i32) -> Result { + self.visit_i64(v as i64) + } + + #[inline] + fn visit_i64(&mut self, v: i64) -> Result; + + #[inline] + fn visit_usize(&mut self, v: usize) -> Result { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u8(&mut self, v: u8) -> Result { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u16(&mut self, v: u16) -> Result { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u32(&mut self, v: u32) -> Result { + self.visit_u64(v as u64) + } + + #[inline] + fn visit_u64(&mut self, v: u64) -> Result; + + #[inline] + fn visit_f32(&mut self, v: f32) -> Result { + self.visit_f64(v as f64) + } + + fn visit_f64(&mut self, v: f64) -> Result; + + #[inline] + fn visit_char(&mut self, v: char) -> Result { + // 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()) + } + + fn visit_str(&mut self, value: &str) -> Result; + + fn visit_unit(&mut self) -> Result; + + #[inline] + fn visit_named_unit(&mut self, _name: &str) -> Result { + self.visit_unit() + } + + #[inline] + fn visit_enum_unit(&mut self, + _name: &str, + _variant: &str) -> Result { + self.visit_unit() + } + + fn visit_none(&mut self) -> Result; + + fn visit_some(&mut self, value: V) -> Result + where V: Serialize; + + fn visit_seq(&mut self, visitor: V) -> Result + where V: SeqVisitor; + + #[inline] + fn visit_named_seq(&mut self, + _name: &'static str, + visitor: V) -> Result + where V: SeqVisitor, + { + self.visit_seq(visitor) + } + + #[inline] + fn visit_enum_seq(&mut self, + _name: &'static str, + _variant: &'static str, + visitor: V) -> Result + where V: SeqVisitor, + { + self.visit_seq(visitor) + } + + fn visit_seq_elt(&mut self, + first: bool, + value: T) -> Result + where T: Serialize; + + fn visit_map(&mut self, visitor: V) -> Result + where V: MapVisitor; + + #[inline] + fn visit_named_map(&mut self, + _name: &'static str, + visitor: V) -> Result + where V: MapVisitor, + { + self.visit_map(visitor) + } + + #[inline] + fn visit_enum_map(&mut self, + _name: &'static str, + _variant: &'static str, + visitor: V) -> Result + where V: MapVisitor, + { + self.visit_map(visitor) + } + + fn visit_map_elt(&mut self, + first: bool, + key: K, + value: V) -> Result + where K: Serialize, + V: Serialize; +} + +pub trait SeqVisitor { + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: Visitor; + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} + +pub trait MapVisitor { + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: Visitor; + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +macro_rules! impl_visit { ($ty:ty, $method:ident) => { - impl, E> Serialize for $ty { + impl Serialize for $ty { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.$method(*self) + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + visitor.$method(*self) } } } } -impl_serialize!(bool, serialize_bool); -impl_serialize!(isize, serialize_isize); -impl_serialize!(i8, serialize_i8); -impl_serialize!(i16, serialize_i16); -impl_serialize!(i32, serialize_i32); -impl_serialize!(i64, serialize_i64); -impl_serialize!(usize, serialize_usize); -impl_serialize!(u8, serialize_u8); -impl_serialize!(u16, serialize_u16); -impl_serialize!(u32, serialize_u32); -impl_serialize!(u64, serialize_u64); -impl_serialize!(f32, serialize_f32); -impl_serialize!(f64, serialize_f64); -impl_serialize!(char, serialize_char); +impl_visit!(bool, visit_bool); +impl_visit!(isize, visit_isize); +impl_visit!(i8, visit_i8); +impl_visit!(i16, visit_i16); +impl_visit!(i32, visit_i32); +impl_visit!(i64, visit_i64); +impl_visit!(usize, visit_usize); +impl_visit!(u8, visit_u8); +impl_visit!(u16, visit_u16); +impl_visit!(u32, visit_u32); +impl_visit!(u64, visit_u64); +impl_visit!(f32, visit_f32); +impl_visit!(f64, visit_f64); +impl_visit!(char, visit_char); -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -impl<'a, S: Serializer, E> Serialize for &'a str { +impl<'a> Serialize for &'a str { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_str(*self) + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + visitor.visit_str(*self) } } -impl, E> Serialize for String { +impl Serialize for String { #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - (&self[]).serialize(s) + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (&self[..]).visit(visitor) } } -////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -macro_rules! impl_serialize_box { - ($ty:ty) => { - impl< - 'a, - S: Serializer, - E, - T: Serialize - > Serialize for $ty { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - (**self).serialize(s) - } +impl Serialize for Option where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + match *self { + Some(ref value) => visitor.visit_some(value), + None => visitor.visit_none(), } } } -impl_serialize_box!(&'a T); -impl_serialize_box!(Box); -impl_serialize_box!(Rc); +/////////////////////////////////////////////////////////////////////////////// -impl< - S: Serializer, - E, - T: Serialize + Send + Sync -> Serialize for Arc { +pub struct SeqIteratorVisitor { + iter: Iter, + first: bool, +} + +impl SeqIteratorVisitor + where Iter: Iterator +{ #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - (**self).serialize(s) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - S: Serializer, - E, - T: Serialize -> Serialize for Option { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_option(self) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - S: Serializer, - E, - T: Serialize -> Serialize for Vec { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_seq(self.iter()) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - S: Serializer, - E, - K: Serialize + Eq + Hash, - V: Serialize -> Serialize for HashMap { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_map(self.iter()) - } -} - -impl< - S: Serializer, - E, - K: Serialize + Ord, - V: Serialize -> Serialize for BTreeMap { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_map(self.iter()) - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl< - S: Serializer, - E, - T: Serialize + Eq + Hash -> Serialize for HashSet { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_seq(self.iter()) - } -} - -impl< - S: Serializer, - E, - T: Serialize + Ord -> Serialize for BTreeSet { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_seq(self.iter()) - } -} - -////////////////////////////////////////////////////////////////////////////// - -macro_rules! peel { - ($name:ident, $($other:ident,)*) => ( impl_serialize_tuple!($($other,)*); ) -} - -macro_rules! impl_serialize_tuple { - () => { - impl, E> Serialize for () { - #[inline] - fn serialize(&self, s: &mut S) -> Result<(), E> { - s.serialize_null() - } + pub fn new(iter: Iter) -> SeqIteratorVisitor { + SeqIteratorVisitor { + iter: iter, + first: true, } - }; - ( $($name:ident,)+ ) => { - impl< - S: Serializer, - E, - $($name:Serialize),+ - > Serialize for ($($name,)+) { - #[inline] - #[allow(non_snake_case)] - fn serialize(&self, s: &mut S) -> Result<(), E> { - // FIXME: how can we count macro args? - let mut len = 0; - $({ let $name = 1; len += $name; })*; - - let ($(ref $name,)*) = *self; - - try!(s.serialize_tuple_start(len)); - $( - try!(s.serialize_tuple_elt($name)); - )* - s.serialize_tuple_end() - } - } - peel!($($name,)*); } } -impl_serialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } +impl SeqVisitor for SeqIteratorVisitor + where T: Serialize, + Iter: Iterator, +{ + #[inline] + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: Visitor, + { + let first = self.first; + self.first = false; + + match self.iter.next() { + Some(value) => { + let value = try!(visitor.visit_seq_elt(first, value)); + Ok(Some(value)) + } + None => Ok(None), + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl<'a, T> Serialize for &'a [T] + where T: Serialize, +{ + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) + } +} + +impl Serialize for Vec where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (&self[..]).visit(visitor) + } +} + +impl Serialize for BTreeSet where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) + } +} + +impl Serialize for HashSet + where T: Serialize + Eq + Hash, + S: HashState, +{ + #[inline] + fn visit(&self, visitor: &mut V) -> Result { + visitor.visit_seq(SeqIteratorVisitor::new(self.iter())) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl Serialize for () { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + visitor.visit_unit() + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// FIXME(rust #19630) Remove this work-around +macro_rules! e { + ($e:expr) => { $e } +} + +macro_rules! tuple_impls { + ($( + $TupleVisitor:ident ($len:expr, $($T:ident),+) { + $($state:pat => $idx:tt,)+ + } + )+) => { + $( + pub struct $TupleVisitor<'a, $($T: 'a),+> { + tuple: &'a ($($T,)+), + state: u8, + first: bool, + } + + impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> { + pub fn new(tuple: &'a ($($T,)+)) -> $TupleVisitor<'a, $($T),+> { + $TupleVisitor { + tuple: tuple, + state: 0, + first: true, + } + } + } + + impl<'a, $($T),+> SeqVisitor for $TupleVisitor<'a, $($T),+> + where $($T: Serialize),+ + { + fn visit(&mut self, visitor: &mut V) -> Result, V::Error> + where V: Visitor, + { + let first = self.first; + self.first = false; + + match self.state { + $( + $state => { + self.state += 1; + Ok(Some(try!(visitor.visit_seq_elt(first, &e!(self.tuple.$idx))))) + } + )+ + _ => { + Ok(None) + } + } + } + + fn size_hint(&self) -> (usize, Option) { + ($len, Some($len)) + } + } + + impl<$($T),+> Serialize for ($($T,)+) + where $($T: Serialize),+ + { + #[inline] + fn visit(&self, visitor: &mut V) -> Result { + visitor.visit_seq($TupleVisitor::new(self)) + } + } + )+ + } +} + +tuple_impls! { + TupleVisitor1 (1, T0) { + 0 => 0, + } + TupleVisitor2 (2, T0, T1) { + 0 => 0, + 1 => 1, + } + TupleVisitor3 (3, T0, T1, T2) { + 0 => 0, + 1 => 1, + 2 => 2, + } + TupleVisitor4 (4, T0, T1, T2, T3) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + } + TupleVisitor5 (5, T0, T1, T2, T3, T4) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + } + TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + } + TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + } + TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + } + TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + } + TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + } + TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + 10 => 10, + } + TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) { + 0 => 0, + 1 => 1, + 2 => 2, + 3 => 3, + 4 => 4, + 5 => 5, + 6 => 6, + 7 => 7, + 8 => 8, + 9 => 9, + 10 => 10, + 11 => 11, + } +} + +/////////////////////////////////////////////////////////////////////////////// + +pub struct MapIteratorVisitor { + iter: Iter, + first: bool, +} + +impl MapIteratorVisitor + where Iter: Iterator +{ + #[inline] + pub fn new(iter: Iter) -> MapIteratorVisitor { + MapIteratorVisitor { + iter: iter, + first: true, + } + } +} + +impl MapVisitor for MapIteratorVisitor + where K: Serialize, + V: Serialize, + I: Iterator, +{ + #[inline] + fn visit(&mut self, visitor: &mut V_) -> Result, V_::Error> + where V_: Visitor, + { + let first = self.first; + self.first = false; + + match self.iter.next() { + Some((key, value)) => { + let value = try!(visitor.visit_map_elt(first, key, value)); + Ok(Some(value)) + } + None => Ok(None) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl Serialize for BTreeMap + where K: Serialize + Ord, + V: Serialize, +{ + #[inline] + fn visit(&self, visitor: &mut V_) -> Result { + visitor.visit_map(MapIteratorVisitor::new(self.iter())) + } +} + +impl Serialize for HashMap + where K: Serialize + Eq + Hash, + V: Serialize, + S: HashState, +{ + #[inline] + fn visit(&self, visitor: &mut V_) -> Result { + visitor.visit_map(MapIteratorVisitor::new(self.iter())) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl<'a, T> Serialize for &'a T where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (**self).visit(visitor) + } +} + +impl<'a, T> Serialize for &'a mut T where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (**self).visit(visitor) + } +} + +impl Serialize for Box where T: Serialize { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (**self).visit(visitor) + } +} + +impl Serialize for Rc where T: Serialize, { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (**self).visit(visitor) + } +} + +impl Serialize for Arc where T: Serialize, { + #[inline] + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + (**self).visit(visitor) + } +} + +/////////////////////////////////////////////////////////////////////////////// + +impl Serialize for path::Path { + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + self.to_str().unwrap().visit(visitor) + } +} + +impl Serialize for path::PathBuf { + fn visit(&self, visitor: &mut V) -> Result + where V: Visitor, + { + self.to_str().unwrap().visit(visitor) + } +} diff --git a/tests/de.rs b/tests/de.rs deleted file mode 100644 index bd992c6f..00000000 --- a/tests/de.rs +++ /dev/null @@ -1,368 +0,0 @@ -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use std::collections::BTreeMap; -use std::{option, string}; - -use serde::de::{Deserializer, Deserialize, Token, TokenKind, IgnoreTokens}; - -macro_rules! treemap { - ($($k:expr => $v:expr),*) => ({ - let mut _m = ::std::collections::BTreeMap::new(); - $(_m.insert($k, $v);)* - _m - }) -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -struct Inner { - a: (), - b: usize, - c: BTreeMap>, -} - -impl< - D: Deserializer, - E -> Deserialize for Inner { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - try!(d.expect_struct_start(token, "Inner")); - - let mut a = None; - let mut b = None; - let mut c = None; - - static FIELDS: &'static [&'static str] = &["a", "b", "c"]; - - loop { - let idx = match try!(d.expect_struct_field_or_end(FIELDS)) { - Some(idx) => idx, - None => { break; } - }; - - match idx { - Some(0) => { a = Some(try!(d.expect_struct_value())); } - Some(1) => { b = Some(try!(d.expect_struct_value())); } - Some(2) => { c = Some(try!(d.expect_struct_value())); } - Some(_) => unreachable!(), - None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); } - } - } - - Ok(Inner { a: a.unwrap(), b: b.unwrap(), c: c.unwrap() }) - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -struct Outer { - inner: Vec, -} - -impl, E> Deserialize for Outer { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - try!(d.expect_struct_start(token, "Outer")); - - static FIELDS: &'static [&'static str] = &["inner"]; - - let mut inner = None; - - loop { - let idx = match try!(d.expect_struct_field_or_end(FIELDS)) { - Some(idx) => idx, - None => { break; } - }; - - match idx { - Some(0) => { inner = Some(try!(d.expect_struct_value())); } - Some(_) => unreachable!(), - None => { let _: IgnoreTokens = try!(Deserialize::deserialize(d)); } - } - } - - Ok(Outer { inner: inner.unwrap() }) - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -enum Animal { - Dog, - Frog(string::String, isize) -} - -impl, E> Deserialize for Animal { - #[inline] - fn deserialize_token(d: &mut D, token: Token) -> Result { - match try!(d.expect_enum_start(token, "Animal", &["Dog", "Frog"])) { - 0 => { - try!(d.expect_enum_end()); - Ok(Animal::Dog) - } - 1 => { - let x0 = try!(Deserialize::deserialize(d)); - let x1 = try!(Deserialize::deserialize(d)); - try!(d.expect_enum_end()); - Ok(Animal::Frog(x0, x1)) - } - _ => unreachable!(), - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Debug)] -enum Error { - EndOfStream, - SyntaxError(Vec), - UnexpectedName, - ConversionError, - MissingField(&'static str), -} - -////////////////////////////////////////////////////////////////////////////// - -struct TokenDeserializer { - tokens: Iter, -} - -impl> TokenDeserializer { - #[inline] - fn new(tokens: Iter) -> TokenDeserializer { - TokenDeserializer { - tokens: tokens, - } - } -} - -impl> Iterator for TokenDeserializer { - type Item = Result; - - #[inline] - fn next(&mut self) -> option::Option> { - self.tokens.next().map(|token| Ok(token)) - } -} - -impl> Deserializer for TokenDeserializer { - fn end_of_stream_error(&mut self) -> Error { - Error::EndOfStream - } - - fn syntax_error(&mut self, _token: Token, expected: &[TokenKind]) -> Error { - Error::SyntaxError(expected.to_vec()) - } - - fn unexpected_name_error(&mut self, _token: Token) -> Error { - Error::UnexpectedName - } - - fn conversion_error(&mut self, _token: Token) -> Error { - Error::ConversionError - } - - #[inline] - fn missing_field< - T: Deserialize, Error> - >(&mut self, field: &'static str) -> Result { - Err(Error::MissingField(field)) - } -} - -////////////////////////////////////////////////////////////////////////////// - -macro_rules! test_value { - ($name:ident, [$($tokens:expr => $value:expr, $ty:ty),*]) => { - #[test] - fn $name() { - $( - let mut deserializer = TokenDeserializer::new($tokens.into_iter()); - let value: $ty = Deserialize::deserialize(&mut deserializer).unwrap(); - - assert_eq!(value, $value); - )+ - } - } -} - -test_value!(test_primitives, [ - vec!(Token::Null) => (), (), - vec!(Token::Bool(true)) => true, bool, - vec!(Token::Bool(false)) => false, bool, - vec!(Token::Isize(5)) => 5, isize, - vec!(Token::I8(5)) => 5, i8, - vec!(Token::I16(5)) => 5, i16, - vec!(Token::I32(5)) => 5, i32, - vec!(Token::I64(5)) => 5, i64, - vec!(Token::Usize(5)) => 5, usize, - vec!(Token::U8(5)) => 5, u8, - vec!(Token::U16(5)) => 5, u16, - vec!(Token::U32(5)) => 5, u32, - vec!(Token::U64(5)) => 5, u64, - vec!(Token::F32(5.0)) => 5.0, f32, - vec!(Token::F64(5.0)) => 5.0, f64, - vec!(Token::Char('c')) => 'c', char, - vec!(Token::Str("abc")) => "abc", &str, - vec!(Token::String("abc".to_string())) => "abc".to_string(), string::String -]); - -test_value!(test_tuples, [ - vec!( - Token::TupleStart(0), - Token::End, - ) => (), (), - - vec!( - Token::TupleStart(2), - Token::Isize(5), - - Token::Str("a"), - Token::End, - ) => (5, "a"), (isize, &'static str), - - vec!( - Token::TupleStart(3), - Token::Null, - - Token::TupleStart(0), - Token::End, - - Token::TupleStart(2), - Token::Isize(5), - - Token::Str("a"), - Token::End, - Token::End, - ) => ((), (), (5, "a")), ((), (), (isize, &'static str)) -]); - -test_value!(test_options, [ - vec!(Token::Option(false)) => None, option::Option, - - vec!( - Token::Option(true), - Token::Isize(5), - ) => Some(5), option::Option -]); - -test_value!(test_structs, [ - vec!( - Token::StructStart("Outer", 1), - Token::Str("inner"), - Token::SeqStart(0), - Token::End, - Token::End, - ) => Outer { inner: vec!() }, Outer, - - vec!( - Token::StructStart("Outer", 1), - Token::Str("inner"), - Token::SeqStart(1), - Token::StructStart("Inner", 3), - Token::Str("a"), - Token::Null, - - Token::Str("b"), - Token::Usize(5), - - Token::Str("c"), - Token::MapStart(1), - Token::String("abc".to_string()), - - Token::Option(true), - Token::Char('c'), - Token::End, - Token::End, - Token::End, - Token::End, - ) => Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: treemap!("abc".to_string() => Some('c')), - }, - ), - }, Outer -]); - -test_value!(test_enums, [ - vec!( - Token::EnumStart("Animal", "Dog", 0), - Token::End, - ) => Animal::Dog, Animal, - - vec!( - Token::EnumStart("Animal", "Frog", 2), - Token::String("Henry".to_string()), - Token::Isize(349), - Token::End, - ) => Animal::Frog("Henry".to_string(), 349), Animal -]); - -test_value!(test_vecs, [ - vec!( - Token::SeqStart(0), - Token::End, - ) => vec!(), Vec, - - vec!( - Token::SeqStart(3), - Token::Isize(5), - - Token::Isize(6), - - Token::Isize(7), - Token::End, - ) => vec!(5, 6, 7), Vec, - - - vec!( - Token::SeqStart(3), - Token::SeqStart(1), - Token::Isize(1), - Token::End, - - Token::SeqStart(2), - Token::Isize(2), - - Token::Isize(3), - Token::End, - - Token::SeqStart(3), - Token::Isize(4), - - Token::Isize(5), - - Token::Isize(6), - Token::End, - Token::End, - ) => vec!(vec!(1), vec!(2, 3), vec!(4, 5, 6)), Vec> -]); - -test_value!(test_treemaps, [ - vec!( - Token::MapStart(0), - Token::End, - ) => treemap!(), BTreeMap, - - vec!( - Token::MapStart(2), - Token::Isize(5), - Token::String("a".to_string()), - - Token::Isize(6), - Token::String("b".to_string()), - Token::End, - ) => treemap!(5is => "a".to_string(), 6is => "b".to_string()), BTreeMap -]); diff --git a/tests/json.rs b/tests/json.rs deleted file mode 100644 index 30978c79..00000000 --- a/tests/json.rs +++ /dev/null @@ -1,1384 +0,0 @@ -#![feature(io, plugin, test)] -#![plugin(serde_macros)] - -extern crate "rustc-serialize" as rustc_serialize; - -extern crate test; -extern crate serde; - -use std::fmt::Debug; -use std::io; -use std::str; -use std::string; -use std::collections::BTreeMap; - -use serde::de; -use serde::ser::{Serialize, Serializer}; -use serde::ser; - -use serde::json::{self, Error, Parser, ToJson, Value, value, from_str, from_json}; - -use serde::json::error::Error::{ - SyntaxError, -}; - -use serde::json::error::ErrorCode::{ - EOFWhileParsingList, - EOFWhileParsingObject, - EOFWhileParsingString, - EOFWhileParsingValue, - ExpectedColon, - ExpectedListCommaOrEnd, - ExpectedObjectCommaOrEnd, - ExpectedSomeIdent, - ExpectedSomeValue, - InvalidNumber, - KeyMustBeAString, - TrailingCharacters, -}; - -macro_rules! treemap { - ($($k:expr => $v:expr),*) => ({ - let mut _m = ::std::collections::BTreeMap::new(); - $(_m.insert($k, $v);)* - _m - }) -} - -#[derive(PartialEq, Debug)] -#[derive_serialize] -#[derive_deserialize] -enum Animal { - Dog, - Frog(String, Vec) -} - -impl ToJson for Animal { - fn to_json(&self) -> Value { - match *self { - Animal::Dog => { - Value::Object( - treemap!( - "Dog".to_string() => Value::Array(vec!()) - ) - ) - } - Animal::Frog(ref x0, ref x1) => { - Value::Object( - treemap!( - "Frog".to_string() => Value::Array(vec!(x0.to_json(), x1.to_json())) - ) - ) - } - } - } -} - -#[derive(PartialEq, Debug)] -#[derive_serialize] -#[derive_deserialize] -struct Inner { - a: (), - b: usize, - c: Vec, -} - -impl ToJson for Inner { - fn to_json(&self) -> Value { - Value::Object( - treemap!( - "a".to_string() => self.a.to_json(), - "b".to_string() => self.b.to_json(), - "c".to_string() => self.c.to_json() - ) - ) - } -} - -#[derive(PartialEq, Debug)] -#[derive_serialize] -#[derive_deserialize] -struct Outer { - inner: Vec, -} - -impl ToJson for Outer { - fn to_json(&self) -> Value { - Value::Object( - treemap!( - "inner".to_string() => self.inner.to_json() - ) - ) - } -} - -fn test_encode_ok< - T: PartialEq + Debug + ToJson + ser::Serialize>, io::Error> ->(errors: &[(T, &str)]) { - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = json::to_string(value).unwrap(); - assert_eq!(s, out); - - let s = json::to_string(&value.to_json()).unwrap(); - assert_eq!(s, out); - } -} - -fn test_pretty_encode_ok< - T: PartialEq + Debug + ToJson + ser::Serialize>, io::Error> ->(errors: &[(T, &str)]) { - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = json::to_pretty_string(value).unwrap(); - assert_eq!(s, out); - - let s = json::to_pretty_string(&value.to_json()).unwrap(); - assert_eq!(s, out); - } -} - -#[test] -fn test_write_null() { - let tests = &[ - ((), "null"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_i64() { - let tests = &[ - (3is, "3"), - (-2is, "-2"), - (-1234is, "-1234"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_f64() { - let tests = &[ - (3.0f64, "3"), - (3.1, "3.1"), - (-1.5, "-1.5"), - (0.5, "0.5"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_str() { - let tests = &[ - ("", "\"\""), - ("foo", "\"foo\""), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_bool() { - let tests = &[ - (true, "true"), - (false, "false"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_list() { - test_encode_ok(&[ - (vec!(), "[]"), - (vec!(true), "[true]"), - (vec!(true, false), "[true,false]"), - ]); - - test_pretty_encode_ok(&[ - (vec!(), "[]"), - ( - vec!(true), - concat!( - "[\n", - " true\n", - "]" - ), - ), - ( - vec!(true, false), - concat!( - "[\n", - " true,\n", - " false\n", - "]" - ), - ), - ]); - - let long_test_list = Value::Array(vec![ - Value::Boolean(false), - Value::Null, - Value::Array(vec![Value::String("foo\nbar".to_string()), Value::Floating(3.5)])]); - - test_encode_ok(&[ - (long_test_list, "[false,null,[\"foo\\nbar\",3.5]]"), - ]); - - let long_test_list = Value::Array(vec![ - Value::Boolean(false), - Value::Null, - Value::Array(vec![Value::String("foo\nbar".to_string()), Value::Floating(3.5)])]); - - test_pretty_encode_ok(&[ - ( - long_test_list, - concat!( - "[\n", - " false,\n", - " null,\n", - " [\n", - " \"foo\\nbar\",\n", - " 3.5\n", - " ]\n", - "]" - ) - ) - ]); -} - -#[test] -fn test_write_object() { - test_encode_ok(&[ - (treemap!(), "{}"), - (treemap!("a".to_string() => true), "{\"a\":true}"), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - "{\"a\":true,\"b\":false}"), - ]); - - test_pretty_encode_ok(&[ - (treemap!(), "{}"), - ( - treemap!("a".to_string() => true), - concat!( - "{\n", - " \"a\": true\n", - "}" - ), - ), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - concat!( - "{\n", - " \"a\": true,\n", - " \"b\": false\n", - "}" - ), - ), - ]); - - let complex_obj = Value::Object(treemap!( - "b".to_string() => Value::Array(vec!( - Value::Object(treemap!("c".to_string() => Value::String("\x0c\r".to_string()))), - Value::Object(treemap!("d".to_string() => Value::String("".to_string()))) - )) - )); - - test_encode_ok(&[ - ( - complex_obj.clone(), - "{\ - \"b\":[\ - {\"c\":\"\\f\\r\"},\ - {\"d\":\"\"}\ - ]\ - }" - ), - ]); - - test_pretty_encode_ok(&[ - ( - complex_obj.clone(), - concat!( - "{\n", - " \"b\": [\n", - " {\n", - " \"c\": \"\\f\\r\"\n", - " },\n", - " {\n", - " \"d\": \"\"\n", - " }\n", - " ]\n", - "}" - ), - ) - ]); -} - -#[test] -fn test_write_tuple() { - test_encode_ok(&[ - ( - (5is,), - "[5]", - ), - ]); - - test_pretty_encode_ok(&[ - ( - (5is,), - concat!( - "[\n", - " 5\n", - "]" - ), - ), - ]); - - test_encode_ok(&[ - ( - (5is, (6is, "abc")), - "[5,[6,\"abc\"]]", - ), - ]); - - test_pretty_encode_ok(&[ - ( - (5is, (6is, "abc")), - concat!( - "[\n", - " 5,\n", - " [\n", - " 6,\n", - " \"abc\"\n", - " ]\n", - "]" - ), - ), - ]); -} - -#[test] -fn test_write_enum() { - test_encode_ok(&[ - (Animal::Dog, "{\"Dog\":[]}"), - (Animal::Frog("Henry".to_string(), vec!()), "{\"Frog\":[\"Henry\",[]]}"), - (Animal::Frog("Henry".to_string(), vec!(349)), "{\"Frog\":[\"Henry\",[349]]}"), - (Animal::Frog("Henry".to_string(), vec!(349, 102)), "{\"Frog\":[\"Henry\",[349,102]]}"), - ]); - - test_pretty_encode_ok(&[ - ( - Animal::Dog, - concat!( - "{\n", - " \"Dog\": []\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec!()), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " []\n", - " ]\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec!(349)), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " [\n", - " 349\n", - " ]\n", - " ]\n", - "}" - ), - ), - ( - Animal::Frog("Henry".to_string(), vec!(349, 102)), - concat!( - "{\n", - " \"Frog\": [\n", - " \"Henry\",\n", - " [\n", - " 349,\n", - " 102\n", - " ]\n", - " ]\n", - "}" - ), - ), - ]); -} - -#[test] -fn test_write_option() { - test_encode_ok(&[ - (None, "null"), - (Some("jodhpurs"), "\"jodhpurs\""), - ]); - - test_encode_ok(&[ - (None, "null"), - (Some(vec!("foo", "bar")), "[\"foo\",\"bar\"]"), - ]); - - test_pretty_encode_ok(&[ - (None, "null"), - (Some("jodhpurs"), "\"jodhpurs\""), - ]); - - test_pretty_encode_ok(&[ - (None, "null"), - ( - Some(vec!("foo", "bar")), - concat!( - "[\n", - " \"foo\",\n", - " \"bar\"\n", - "]" - ), - ), - ]); - -} - -// FIXME (#5527): these could be merged once UFCS is finished. -fn test_parse_err< - 'a, - T: Debug + de::Deserialize>, Error> ->(errors: &[(&'a str, Error)]) { - for &(s, ref err) in errors { - let v: Result = from_str(s); - assert_eq!(v.unwrap_err(), *err); - } -} - -fn test_parse_ok< - 'a, - T: PartialEq + Debug + ToJson + de::Deserialize>, Error> ->(errors: &[(&'a str, T)]) { - for &(s, ref value) in errors { - let v: T = from_str(s).unwrap(); - assert_eq!(v, *value); - - let v: Value = from_str(s).unwrap(); - assert_eq!(v, value.to_json()); - } -} - -fn test_json_deserialize_ok< - T: PartialEq + Debug + ToJson + de::Deserialize ->(errors: &[T]) { - for value in errors { - let v: T = from_json(value.to_json()).unwrap(); - assert_eq!(v, *value); - - // Make sure we can round trip back to `Json`. - let v: Value = from_json(value.to_json()).unwrap(); - assert_eq!(v, value.to_json()); - } -} - -#[test] -fn test_parse_null() { - test_parse_err::<()>(&[ - ("n", SyntaxError(ExpectedSomeIdent, 1, 2)), - ("nul", SyntaxError(ExpectedSomeIdent, 1, 4)), - ("nulla", SyntaxError(TrailingCharacters, 1, 5)), - ]); - - test_parse_ok(&[ - ("null", ()), - ]); -} - -#[test] -fn test_json_deserialize_null() { - test_json_deserialize_ok(&[ - (), - ]); -} - -#[test] -fn test_parse_bool() { - test_parse_err::(&[ - ("t", SyntaxError(ExpectedSomeIdent, 1, 2)), - ("truz", SyntaxError(ExpectedSomeIdent, 1, 4)), - ("f", SyntaxError(ExpectedSomeIdent, 1, 2)), - ("faz", SyntaxError(ExpectedSomeIdent, 1, 3)), - ("truea", SyntaxError(TrailingCharacters, 1, 5)), - ("falsea", SyntaxError(TrailingCharacters, 1, 6)), - ]); - - test_parse_ok(&[ - ("true", true), - ("false", false), - ]); -} - -#[test] -fn test_json_deserialize_bool() { - test_json_deserialize_ok(&[ - true, - false, - ]); -} - -#[test] -fn test_parse_number_errors() { - test_parse_err::(&[ - ("+", SyntaxError(ExpectedSomeValue, 1, 1)), - (".", SyntaxError(ExpectedSomeValue, 1, 1)), - ("-", SyntaxError(InvalidNumber, 1, 2)), - ("00", SyntaxError(InvalidNumber, 1, 2)), - ("1.", SyntaxError(InvalidNumber, 1, 3)), - ("1e", SyntaxError(InvalidNumber, 1, 3)), - ("1e+", SyntaxError(InvalidNumber, 1, 4)), - ("1a", SyntaxError(TrailingCharacters, 1, 2)), - ]); -} - -#[test] -fn test_parse_i64() { - test_parse_ok(&[ - ("3", 3i64), - ("-2", -2), - ("-1234", -1234), - ]); -} - -#[test] -fn test_parse_f64() { - test_parse_ok(&[ - ("3.0", 3.0f64), - ("3.1", 3.1), - ("-1.2", -1.2), - ("0.4", 0.4), - ("0.4e5", 0.4e5), - ("0.4e15", 0.4e15), - ("0.4e-01", 0.4e-01), - ]); -} - -#[test] -fn test_json_deserialize_numbers() { - test_json_deserialize_ok(&[ - 3.0f64, - 3.1, - -1.2, - 0.4, - 0.4e5, - 0.4e15, - 0.4e-01, - ]); -} - -#[test] -fn test_parse_string() { - test_parse_err::(&[ - ("\"", SyntaxError(EOFWhileParsingString, 1, 2)), - ("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)), - ("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)), - ]); - - test_parse_ok(&[ - ("\"\"", "".to_string()), - ("\"foo\"", "foo".to_string()), - ("\"\\\"\"", "\"".to_string()), - ("\"\\b\"", "\x08".to_string()), - ("\"\\n\"", "\n".to_string()), - ("\"\\r\"", "\r".to_string()), - ("\"\\t\"", "\t".to_string()), - ("\"\\u12ab\"", "\u{12ab}".to_string()), - ("\"\\uAB12\"", "\u{AB12}".to_string()), - ]); -} - -#[test] -fn test_json_deserialize_str() { - test_json_deserialize_ok(&[ - "".to_string(), - "foo".to_string(), - "\"".to_string(), - "\x08".to_string(), - "\n".to_string(), - "\r".to_string(), - "\t".to_string(), - "\u{12ab}".to_string(), - "\u{AB12}".to_string(), - ]); -} - -#[test] -fn test_parse_list() { - test_parse_err::>(&[ - ("[", SyntaxError(EOFWhileParsingValue, 1, 2)), - ("[ ", SyntaxError(EOFWhileParsingValue, 1, 3)), - ("[1", SyntaxError(EOFWhileParsingList, 1, 3)), - ("[1,", SyntaxError(EOFWhileParsingValue, 1, 4)), - ("[1,]", SyntaxError(ExpectedSomeValue, 1, 4)), - ("[1 2]", SyntaxError(ExpectedListCommaOrEnd, 1, 4)), - ("[]a", SyntaxError(TrailingCharacters, 1, 3)), - ]); - - test_parse_ok(&[ - ("[]", vec!()), - ("[ ]", vec!()), - ("[null]", vec!(())), - ("[ null ]", vec!(())), - ]); - - test_parse_ok(&[ - ("[true]", vec!(true)), - ]); - - test_parse_ok(&[ - ("[3,1]", vec!(3is, 1)), - ("[ 3 , 1 ]", vec!(3is, 1)), - ]); - - test_parse_ok(&[ - ("[[3], [1, 2]]", vec!(vec!(3is), vec!(1, 2))), - ]); - - let v: () = from_str("[]").unwrap(); - assert_eq!(v, ()); - - test_parse_ok(&[ - ("[1, 2, 3]", (1us, 2us, 3us)), - ]); -} - -#[test] -fn test_json_deserialize_list() { - test_json_deserialize_ok(&[ - vec!(), - vec!(()), - ]); - - test_json_deserialize_ok(&[ - vec!(true), - ]); - - test_json_deserialize_ok(&[ - vec!(3is, 1), - ]); - - test_json_deserialize_ok(&[ - vec!(vec!(3is), vec!(1, 2)), - ]); -} - -#[test] -fn test_parse_object() { - test_parse_err::>(&[ - ("{", SyntaxError(EOFWhileParsingString, 1, 2)), - ("{ ", SyntaxError(EOFWhileParsingString, 1, 3)), - ("{1", SyntaxError(KeyMustBeAString, 1, 2)), - ("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)), - ("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)), - ("{\"a\" ", SyntaxError(EOFWhileParsingObject, 1, 6)), - ("{\"a\" 1", SyntaxError(ExpectedColon, 1, 6)), - ("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)), - ("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)), - ("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)), - ("{\"a\":1,", SyntaxError(EOFWhileParsingString, 1, 8)), - ("{}a", SyntaxError(TrailingCharacters, 1, 3)), - ]); - - test_parse_ok(&[ - ("{}", treemap!()), - ("{ }", treemap!()), - ( - "{\"a\":3}", - treemap!("a".to_string() => 3is) - ), - ( - "{ \"a\" : 3 }", - treemap!("a".to_string() => 3is) - ), - ( - "{\"a\":3,\"b\":4}", - treemap!("a".to_string() => 3is, "b".to_string() => 4) - ), - ( - "{ \"a\" : 3 , \"b\" : 4 }", - treemap!("a".to_string() => 3is, "b".to_string() => 4), - ), - ]); - - test_parse_ok(&[ - ( - "{\"a\": {\"b\": 3, \"c\": 4}}", - treemap!("a".to_string() => treemap!("b".to_string() => 3is, "c".to_string() => 4is)), - ), - ]); -} - -#[test] -fn test_json_deserialize_object() { - test_json_deserialize_ok(&[ - treemap!(), - treemap!("a".to_string() => 3is), - treemap!("a".to_string() => 3is, "b".to_string() => 4), - ]); - - test_json_deserialize_ok(&[ - treemap!("a".to_string() => treemap!("b".to_string() => 3is, "c".to_string() => 4)), - ]); -} - -#[test] -fn test_parse_struct() { - test_parse_ok(&[ - ( - "{ - \"inner\": [] - }", - Outer { - inner: vec![] - }, - ), - ( - "{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }", - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ] - }, - ) - ]); -} - -#[test] -fn test_json_deserialize_struct() { - test_json_deserialize_ok(&[ - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ] - }, - ]); -} - -#[test] -fn test_parse_option() { - test_parse_ok(&[ - ("null", None), - ("\"jodhpurs\"", Some("jodhpurs".to_string())), - ]); - - #[derive(PartialEq, Debug)] - #[derive_serialize] - #[derive_deserialize] - struct Foo { - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{ \"x\": 5 }").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_json_deserialize_option() { - test_json_deserialize_ok(&[ - None, - Some("jodhpurs".to_string()), - ]); -} - -#[test] -fn test_parse_enum() { - test_parse_ok(&[ - ("{\"Dog\": []}", Animal::Dog), - ( - "{\"Frog\": [\"Henry\", []]}", - Animal::Frog("Henry".to_string(), vec!()), - ), - ( - "{\"Frog\": [\"Henry\", [349]]}", - Animal::Frog("Henry".to_string(), vec!(349)), - ), - ( - "{\"Frog\": [\"Henry\", [349, 102]]}", - Animal::Frog("Henry".to_string(), vec!(349, 102)), - ), - ]); - - test_parse_ok(&[ - ( - concat!( - "{", - " \"a\": {\"Dog\": []},", - " \"b\": {\"Frog\":[\"Henry\", []]}", - "}" - ), - treemap!( - "a".to_string() => Animal::Dog, - "b".to_string() => Animal::Frog("Henry".to_string(), vec!()) - ) - ), - ]); -} - -#[test] -fn test_json_deserialize_enum() { - test_json_deserialize_ok(&[ - Animal::Dog, - Animal::Frog("Henry".to_string(), vec!()), - Animal::Frog("Henry".to_string(), vec!(349)), - Animal::Frog("Henry".to_string(), vec!(349, 102)), - ]); -} - -#[test] -fn test_multiline_errors() { - test_parse_err::>(&[ - ("{\n \"foo\":\n \"bar\"", SyntaxError(EOFWhileParsingObject, 3us, 8us)), - ]); -} - -/* -#[derive(Decodable)] -struct DecodeStruct { - x: f64, - y: bool, - z: String, - w: Vec -} -#[derive(Decodable)] -enum DecodeEnum { - A(f64), - B(String) -} -fn check_err>(to_parse: &'static str, - expected: DecoderError) { - let res: DecodeResult = match from_str(to_parse) { - Err(e) => Err(ParseError(e)), - Ok(json) => RustcDecodable::decode(&mut Decoder::new(json)) - }; - match res { - Ok(_) => panic!("`{}` parsed & decoded ok, expecting error `{}`", - to_parse, expected), - Err(ParseError(e)) => panic!("`{}` is not valid json: {}", - to_parse, e), - Err(e) => { - assert_eq!(e, expected); - } - } -} -#[test] -fn test_decode_errors_struct() { - check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); - check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - ExpectedError("Number".to_string(), "true".to_string())); - check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - ExpectedError("Boolean".to_string(), "[]".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - ExpectedError("String".to_string(), "{}".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - ExpectedError("List".to_string(), "null".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", - MissingFieldError("w".to_string())); -} -#[test] -fn test_decode_errors_enum() { - check_err::("{}", - MissingFieldError("variant".to_string())); - check_err::("{\"variant\": 1}", - ExpectedError("String".to_string(), "1".to_string())); - check_err::("{\"variant\": \"A\"}", - MissingFieldError("fields".to_string())); - check_err::("{\"variant\": \"A\", \"fields\": null}", - ExpectedError("List".to_string(), "null".to_string())); - check_err::("{\"variant\": \"C\", \"fields\": []}", - UnknownVariantError("C".to_string())); -} -*/ - -#[test] -fn test_find(){ - let json_value: Value = from_str("{\"dog\" : \"cat\"}").unwrap(); - let found_str = json_value.find(&"dog".to_string()); - assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == "cat"); -} - -#[test] -fn test_find_path(){ - let json_value: Value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.find_path(&[&"dog".to_string(), - &"cat".to_string(), &"mouse".to_string()]); - assert!(found_str.is_some() && found_str.unwrap().as_string().unwrap() == "cheese"); -} - -#[test] -fn test_search(){ - let json_value: Value = from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.search(&"mouse".to_string()).and_then(|j| j.as_string()); - assert!(found_str.is_some()); - assert!(found_str.unwrap() == "cheese"); -} - -#[test] -fn test_is_object() { - let json_value: Value = from_str("{}").unwrap(); - assert!(json_value.is_object()); -} - -#[test] -fn test_as_object() { - let json_value: Value = from_str("{}").unwrap(); - let map = BTreeMap::::new(); - let json_object = json_value.as_object(); - assert_eq!(json_object, Some(&map)); -} - -#[test] -fn test_is_array() { - let json_value: Value = from_str("[1, 2, 3]").unwrap(); - assert!(json_value.is_array()); -} - -#[test] -fn test_as_array() { - let json_value: Value = from_str("[1, 2, 3]").unwrap(); - let json_list = json_value.as_array(); - let expected_length = 3; - assert!(json_list.is_some() && json_list.unwrap().len() == expected_length); -} - -#[test] -fn test_is_string() { - let json_value: Value = from_str("\"dog\"").unwrap(); - assert!(json_value.is_string()); -} - -#[test] -fn test_as_string() { - let json_value: Value = from_str("\"dog\"").unwrap(); - let json_str = json_value.as_string(); - let expected_str = "dog"; - assert_eq!(json_str, Some(expected_str)); -} - -#[test] -fn test_is_number() { - let json_value: Value = from_str("12").unwrap(); - assert!(json_value.is_number()); - - let json_value: Value = from_str("12.0").unwrap(); - assert!(json_value.is_number()); -} - -#[test] -fn test_is_i64() { - let json_value: Value = from_str("12").unwrap(); - assert!(json_value.is_i64()); - - let json_value: Value = from_str("12.0").unwrap(); - assert!(!json_value.is_i64()); -} - -#[test] -fn test_is_f64() { - let json_value: Value = from_str("12").unwrap(); - assert!(!json_value.is_f64()); - - let json_value: Value = from_str("12.0").unwrap(); - assert!(json_value.is_f64()); -} - -#[test] -fn test_as_i64() { - let json_value: Value = from_str("12").unwrap(); - assert_eq!(json_value.as_i64(), Some(12)); -} - -#[test] -fn test_as_f64() { - let json_value: Value = from_str("12").unwrap(); - assert_eq!(json_value.as_f64(), Some(12.0)); -} - -#[test] -fn test_is_boolean() { - let json_value: Value = from_str("false").unwrap(); - assert!(json_value.is_boolean()); -} - -#[test] -fn test_as_boolean() { - let json_value: Value = from_str("false").unwrap(); - let json_bool = json_value.as_boolean(); - let expected_bool = false; - assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); -} - -#[test] -fn test_is_null() { - let json_value: Value = from_str("null").unwrap(); - assert!(json_value.is_null()); -} - -#[test] -fn test_as_null() { - let json_value: Value = from_str("null").unwrap(); - let json_null = json_value.as_null(); - let expected_null = (); - assert!(json_null.is_some() && json_null.unwrap() == expected_null); -} - -/* -#[test] -fn test_encode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = MemWriter::new(); - { - let mut serializer = Serializer::new(&mut mem_buf as &mut Writer); - hm.serialize(&mut serializer).unwrap(); - } - let bytes = mem_buf.unwrap(); - let json_str = from_utf8(&bytes).unwrap(); - let _json_value: Value = from_str(json_str).unwrap(); -} -#[test] -fn test_prettyencode_hashmap_with_numeric_key() { - use std::str::from_utf8; - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let mut mem_buf = MemWriter::new(); - { - let mut serializer = PrettySerializer::new(&mut mem_buf as &mut Writer); - hm.serialize(&mut serializer).unwrap() - } - let bytes = mem_buf.unwrap(); - let json_str = from_utf8(&bytes).unwrap(); - let _json_value: Value = from_str(json_str).unwrap(); -} - -#[test] -fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { - use std::collections::HashMap; - let json_str = "{\"1\":true}"; - let map: HashMap = from_str(json_str).unwrap(); - let mut m = HashMap::new(); - m.insert(1u, true); - assert_eq!(map, m); -} -*/ - -/* -fn assert_stream_equal(src: &str, expected: ~[(JsonEvent, ~[StackElement])]) { - let mut parser = Parser::new(src.chars()); - let mut i = 0; - loop { - let evt = match parser.next() { - Some(e) => e, - None => { break; } - }; - let (ref expected_evt, ref expected_stack) = expected[i]; - if !parser.stack().is_equal_to(&expected_stack) { - panic!("Parser stack is not equal to {}", expected_stack); - } - assert_eq!(&evt, expected_evt); - i+=1; - } -} -#[test] -fn test_streaming_parser() { - assert_stream_equal( - r#"{ "foo":"bar", "array" : [0, 1, 2,3 ,4,5], "idents":[null,true,false]}"#, - ~[ - (ObjectStart, ~[]), - (StringValue("bar".to_string()), ~[Key("foo")]), - (ListStart, ~[Key("array")]), - (NumberValue(0.0), ~[Key("array"), Index(0)]), - (NumberValue(1.0), ~[Key("array"), Index(1)]), - (NumberValue(2.0), ~[Key("array"), Index(2)]), - (NumberValue(3.0), ~[Key("array"), Index(3)]), - (NumberValue(4.0), ~[Key("array"), Index(4)]), - (NumberValue(5.0), ~[Key("array"), Index(5)]), - (ListEnd, ~[Key("array")]), - (ListStart, ~[Key("idents")]), - (NullValue, ~[Key("idents"), Index(0)]), - (BooleanValue(true), ~[Key("idents"), Index(1)]), - (BooleanValue(false), ~[Key("idents"), Index(2)]), - (ListEnd, ~[Key("idents")]), - (ObjectEnd, ~[]), - ] - ); -} -fn last_event(src: &str) -> JsonEvent { - let mut parser = Parser::new(src.chars()); - let mut evt = NullValue; - loop { - evt = match parser.next() { - Some(e) => e, - None => return evt, - } - } -} -#[test] -#[ignore(cfg(target_word_size = "32"))] // FIXME(#14064) -fn test_read_object_streaming() { - assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); - assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); - assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); - assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - - assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); - assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); - assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); - assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); - assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); - - assert_stream_equal( - "{}", - box [(ObjectStart, box []), (ObjectEnd, box [])] - ); - assert_stream_equal( - "{\"a\": 3}", - box [ - (ObjectStart, box []), - (F64Value(3.0), box [Key("a")]), - (ObjectEnd, box []), - ] - ); - assert_stream_equal( - "{ \"a\": null, \"b\" : true }", - box [ - (ObjectStart, box []), - (NullValue, box [Key("a")]), - (BooleanValue(true), box [Key("b")]), - (ObjectEnd, box []), - ] - ); - assert_stream_equal( - "{\"a\" : 1.0 ,\"b\": [ true ]}", - box [ - (ObjectStart, box []), - (F64Value(1.0), box [Key("a")]), - (ListStart, box [Key("b")]), - (BooleanValue(true),box [Key("b"), Index(0)]), - (ListEnd, box [Key("b")]), - (ObjectEnd, box []), - ] - ); - assert_stream_equal( - r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} } - ] - }"#, - ~[ - (ObjectStart, ~[]), - (F64Value(1.0), ~[Key("a")]), - (ListStart, ~[Key("b")]), - (BooleanValue(true), ~[Key("b"), Index(0)]), - (StringValue("foo\nbar".to_string()), ~[Key("b"), Index(1)]), - (ObjectStart, ~[Key("b"), Index(2)]), - (ObjectStart, ~[Key("b"), Index(2), Key("c")]), - (NullValue, ~[Key("b"), Index(2), Key("c"), Key("d")]), - (ObjectEnd, ~[Key("b"), Index(2), Key("c")]), - (ObjectEnd, ~[Key("b"), Index(2)]), - (ListEnd, ~[Key("b")]), - (ObjectEnd, ~[]), - ] - ); -} -#[test] -#[ignore(cfg(target_word_size = "32"))] // FIXME(#14064) -fn test_read_list_streaming() { - assert_stream_equal( - "[]", - box [ - (ListStart, box []), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[ ]", - box [ - (ListStart, box []), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[true]", - box [ - (ListStart, box []), - (BooleanValue(true), box [Index(0)]), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[ false ]", - box [ - (ListStart, box []), - (BooleanValue(false), box [Index(0)]), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[null]", - box [ - (ListStart, box []), - (NullValue, box [Index(0)]), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[3, 1]", - box [ - (ListStart, box []), - (F64Value(3.0), box [Index(0)]), - (F64Value(1.0), box [Index(1)]), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "\n[3, 2]\n", - box [ - (ListStart, box []), - (F64Value(3.0), box [Index(0)]), - (F64Value(2.0), box [Index(1)]), - (ListEnd, box []), - ] - ); - assert_stream_equal( - "[2, [4, 1]]", - box [ - (ListStart, box []), - (F64Value(2.0), box [Index(0)]), - (ListStart, box [Index(1)]), - (F64Value(4.0), box [Index(1), Index(0)]), - (F64Value(1.0), box [Index(1), Index(1)]), - (ListEnd, box [Index(1)]), - (ListEnd, box []), - ] - ); - - assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); - - assert_eq!(from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); - assert_eq!(from_str("[1"), Err(SyntaxError(EOFWhileParsingList, 1, 3))); - assert_eq!(from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); - assert_eq!(from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - -} -#[test] -fn test_trailing_characters_streaming() { - assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); - assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); - assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); - assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); -} -#[test] -fn test_read_identifiers_streaming() { - assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); - assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); - assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); - - assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); -} - -#[test] -fn test_stack() { - let mut stack = Stack::new(); - - assert!(stack.is_empty()); - assert!(stack.len() == 0); - assert!(!stack.last_is_index()); - - stack.push_index(0); - stack.bump_index(); - - assert!(stack.len() == 1); - assert!(stack.is_equal_to(&[Index(1)])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1)])); - assert!(stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - - stack.push_key("foo".to_string()); - - assert!(stack.len() == 2); - assert!(stack.is_equal_to(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1), Key("foo")])); - assert!(stack.ends_with(&[Key("foo")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); - - stack.push_key("bar".to_string()); - - assert!(stack.len() == 3); - assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo"), Key("bar")])); - assert!(stack.ends_with(&[Key("bar")])); - assert!(stack.ends_with(&[Key("foo"), Key("bar")])); - assert!(stack.ends_with(&[Index(1), Key("foo"), Key("bar")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); - assert!(stack.get(2) == Key("bar")); - - stack.pop(); - - assert!(stack.len() == 2); - assert!(stack.is_equal_to(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1), Key("foo")])); - assert!(stack.ends_with(&[Key("foo")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); -} -*/ diff --git a/tests/json_struct.rs b/tests/json_struct.rs deleted file mode 100644 index bcd5998b..00000000 --- a/tests/json_struct.rs +++ /dev/null @@ -1,30 +0,0 @@ -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -#[derive(PartialEq, Debug)] -#[derive_serialize] -#[derive_deserialize] -struct Test { - #[serial_name = "$schema"] - schema: String, - title: String, - #[serial_name = "type"] - ty: isize -} - -#[test] -fn test_json_struct() { - let input = Test { - schema: "a".to_string(), - title: "b".to_string(), - ty: 3, - }; - - let s = serde::json::to_string(&input).unwrap(); - assert_eq!(&s[], r#"{"$schema":"a","title":"b","type":3}"#); - - let output: Test = serde::json::from_str(&s).unwrap(); - assert_eq!(input, output); -} diff --git a/tests/ser.rs b/tests/ser.rs deleted file mode 100644 index c70ca3b7..00000000 --- a/tests/ser.rs +++ /dev/null @@ -1,517 +0,0 @@ -#![feature(plugin)] -#![plugin(serde_macros)] - -extern crate serde; - -use std::collections::{HashMap, BTreeMap}; -use std::{option, string}; - -use serde::ser::{Serializer, Serialize}; - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -#[derive_serialize] -struct Inner { - a: (), - b: usize, - c: HashMap>, -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -#[derive_serialize] -struct Outer { - inner: Vec, -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -#[derive_serialize] -enum Animal { - Dog, - Frog(String, isize) -} - -////////////////////////////////////////////////////////////////////////////// - -#[derive(Clone, PartialEq, Debug)] -pub enum Token<'a> { - Null, - Bool(bool), - Isize(isize), - I8(i8), - I16(i16), - I32(i32), - I64(i64), - Usize(usize), - U8(u8), - U16(u16), - U32(u32), - U64(u64), - F32(f32), - F64(f64), - Char(char), - Str(&'a str), - - TupleStart(usize), - TupleSep, - TupleEnd, - - StructStart(&'a str, usize), - StructSep(&'a str), - StructEnd, - - EnumStart(&'a str, &'a str, usize), - EnumSep, - EnumEnd, - - Option(bool), - - SeqStart(usize), - SeqEnd, - - MapStart(usize), - MapEnd, -} - -#[derive(Debug)] -#[allow(dead_code)] -enum Error { - EndOfStream, - SyntaxError, -} - -////////////////////////////////////////////////////////////////////////////// - -struct AssertSerializer { - iter: Iter, -} - -impl<'a, Iter: Iterator>> AssertSerializer { - fn new(iter: Iter) -> AssertSerializer { - AssertSerializer { - iter: iter, - } - } - - fn serialize<'b>(&mut self, token: Token<'b>) -> Result<(), Error> { - let t = match self.iter.next() { - Some(t) => t, - None => { panic!(); } - }; - - assert_eq!(t, token); - - Ok(()) - } -} - -impl<'a, Iter: Iterator>> Serializer for AssertSerializer { - fn serialize_null(&mut self) -> Result<(), Error> { - self.serialize(Token::Null) - } - fn serialize_bool(&mut self, v: bool) -> Result<(), Error> { - self.serialize(Token::Bool(v)) - } - fn serialize_isize(&mut self, v: isize) -> Result<(), Error> { - self.serialize(Token::Isize(v)) - } - - fn serialize_i8(&mut self, v: i8) -> Result<(), Error> { - self.serialize(Token::I8(v)) - } - - fn serialize_i16(&mut self, v: i16) -> Result<(), Error> { - self.serialize(Token::I16(v)) - } - - fn serialize_i32(&mut self, v: i32) -> Result<(), Error> { - self.serialize(Token::I32(v)) - } - - fn serialize_i64(&mut self, v: i64) -> Result<(), Error> { - self.serialize(Token::I64(v)) - } - - fn serialize_usize(&mut self, v: usize) -> Result<(), Error> { - self.serialize(Token::Usize(v)) - } - - fn serialize_u8(&mut self, v: u8) -> Result<(), Error> { - self.serialize(Token::U8(v)) - } - - fn serialize_u16(&mut self, v: u16) -> Result<(), Error> { - self.serialize(Token::U16(v)) - } - - fn serialize_u32(&mut self, v: u32) -> Result<(), Error> { - self.serialize(Token::U32(v)) - } - - fn serialize_u64(&mut self, v: u64) -> Result<(), Error> { - self.serialize(Token::U64(v)) - } - - fn serialize_f32(&mut self, v: f32) -> Result<(), Error> { - self.serialize(Token::F32(v)) - } - - fn serialize_f64(&mut self, v: f64) -> Result<(), Error> { - self.serialize(Token::F64(v)) - } - - fn serialize_char(&mut self, v: char) -> Result<(), Error> { - self.serialize(Token::Char(v)) - } - - fn serialize_str(&mut self, v: &str) -> Result<(), Error> { - self.serialize(Token::Str(v)) - } - - fn serialize_tuple_start(&mut self, len: usize) -> Result<(), Error> { - self.serialize(Token::TupleStart(len)) - } - - fn serialize_tuple_elt< - T: Serialize, Error> - >(&mut self, value: &T) -> Result<(), Error> { - try!(self.serialize(Token::TupleSep)); - value.serialize(self) - } - - fn serialize_tuple_end(&mut self) -> Result<(), Error> { - self.serialize(Token::TupleEnd) - } - - fn serialize_struct_start(&mut self, name: &str, len: usize) -> Result<(), Error> { - self.serialize(Token::StructStart(name, len)) - } - - fn serialize_struct_elt< - T: Serialize, Error> - >(&mut self, name: &str, value: &T) -> Result<(), Error> { - try!(self.serialize(Token::StructSep(name))); - value.serialize(self) - } - - fn serialize_struct_end(&mut self) -> Result<(), Error> { - self.serialize(Token::StructEnd) - } - - fn serialize_enum_start(&mut self, name: &str, variant: &str, len: usize) -> Result<(), Error> { - self.serialize(Token::EnumStart(name, variant, len)) - } - - fn serialize_enum_elt< - T: Serialize, Error> - >(&mut self, value: &T) -> Result<(), Error> { - try!(self.serialize(Token::EnumSep)); - value.serialize(self) - } - - fn serialize_enum_end(&mut self) -> Result<(), Error> { - self.serialize(Token::EnumEnd) - } - - fn serialize_option< - T: Serialize, Error> - >(&mut self, v: &option::Option) -> Result<(), Error> { - match *v { - Some(ref v) => { - try!(self.serialize(Token::Option(true))); - v.serialize(self) - } - None => { - self.serialize(Token::Option(false)) - } - } - } - - fn serialize_seq< - T: Serialize, Error>, - SeqIter: Iterator - >(&mut self, iter: SeqIter) -> Result<(), Error> { - let (len, _) = iter.size_hint(); - try!(self.serialize(Token::SeqStart(len))); - for elt in iter { - try!(elt.serialize(self)); - } - self.serialize(Token::SeqEnd) - } - - fn serialize_map< - K: Serialize, Error>, - V: Serialize, Error>, - MapIter: Iterator - >(&mut self, iter: MapIter) -> Result<(), Error> { - let (len, _) = iter.size_hint(); - try!(self.serialize(Token::MapStart(len))); - for (key, value) in iter { - try!(key.serialize(self)); - try!(value.serialize(self)); - } - self.serialize(Token::MapEnd) - } -} - -////////////////////////////////////////////////////////////////////////////// - -#[test] -fn test_tokens_int() { - let tokens = vec!( - Token::Isize(5) - ); - let mut serializer = AssertSerializer::new(tokens.into_iter()); - 5is.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_str() { - let tokens = vec!( - Token::Str("a"), - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - "a".serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_null() { - let tokens = vec!( - Token::Null, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - ().serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_option_none() { - let tokens = vec!( - Token::Option(false), - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - None::.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_option_some() { - let tokens = vec!( - Token::Option(true), - Token::Isize(5), - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - Some(5is).serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_tuple() { - let tokens = vec!( - Token::TupleStart(2), - Token::TupleSep, - Token::Isize(5), - - Token::TupleSep, - Token::Str("a"), - Token::TupleEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - (5is, "a").serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_tuple_compound() { - let tokens = vec!( - Token::TupleStart(3), - Token::TupleSep, - Token::Null, - - Token::TupleSep, - Token::Null, - - Token::TupleSep, - Token::TupleStart(2), - Token::TupleSep, - Token::Isize(5), - - Token::TupleSep, - Token::Str("a"), - Token::TupleEnd, - Token::TupleEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - ((), (), (5is, "a")).serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_struct_empty() { - let tokens = vec!( - Token::StructStart("Outer", 1), - Token::StructSep("inner"), - Token::SeqStart(0), - Token::SeqEnd, - Token::StructEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - Outer { inner: vec!() }.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_struct() { - let tokens = vec!( - Token::StructStart("Outer", 1), - Token::StructSep("inner"), - Token::SeqStart(1), - Token::StructStart("Inner", 3), - Token::StructSep("a"), - Token::Null, - - Token::StructSep("b"), - Token::Usize(5), - - Token::StructSep("c"), - Token::MapStart(1), - Token::Str("abc"), - Token::Option(true), - Token::Char('c'), - Token::MapEnd, - Token::StructEnd, - Token::SeqEnd, - Token::StructEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - - let mut map = HashMap::new(); - map.insert("abc".to_string(), Some('c')); - - Outer { - inner: vec!( - Inner { - a: (), - b: 5, - c: map, - }, - ) - }.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_enum() { - let tokens = vec!( - Token::EnumStart("Animal", "Dog", 0), - Token::EnumEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - Animal::Dog.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); - - let tokens = vec!( - Token::EnumStart("Animal", "Frog", 2), - Token::EnumSep, - Token::Str("Henry"), - - Token::EnumSep, - Token::Isize(349), - Token::EnumEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - Animal::Frog("Henry".to_string(), 349).serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_vec_empty() { - let tokens = vec!( - Token::SeqStart(0), - Token::SeqEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - let v: Vec = vec!(); - v.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_vec() { - let tokens = vec!( - Token::SeqStart(3), - Token::Isize(5), - Token::Isize(6), - Token::Isize(7), - Token::SeqEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - (vec!(5is, 6, 7)).serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_vec_compound() { - let tokens = vec!( - Token::SeqStart(3), - Token::SeqStart(1), - Token::Isize(1), - Token::SeqEnd, - - Token::SeqStart(2), - Token::Isize(2), - Token::Isize(3), - Token::SeqEnd, - - Token::SeqStart(3), - Token::Isize(4), - Token::Isize(5), - Token::Isize(6), - Token::SeqEnd, - Token::SeqEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - (vec!(vec!(1is), vec!(2, 3), vec!(4, 5, 6))).serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} - -#[test] -fn test_tokens_treemap() { - let tokens = vec!( - Token::MapStart(2), - Token::Isize(5), - Token::Str("a"), - - Token::Isize(6), - Token::Str("b"), - Token::MapEnd, - ); - - let mut serializer = AssertSerializer::new(tokens.into_iter()); - - let mut map = BTreeMap::new(); - map.insert(5is, "a".to_string()); - map.insert(6is, "b".to_string()); - - map.serialize(&mut serializer).unwrap(); - assert_eq!(serializer.iter.next(), None); -} diff --git a/serde2/tests/test_de.rs b/tests/test_de.rs similarity index 99% rename from serde2/tests/test_de.rs rename to tests/test_de.rs index 8f35c869..0c07c7af 100644 --- a/serde2/tests/test_de.rs +++ b/tests/test_de.rs @@ -1,14 +1,14 @@ #![feature(custom_derive, plugin, test)] -#![plugin(serde2_macros)] +#![plugin(serde_macros)] extern crate test; -extern crate serde2; +extern crate serde; use std::collections::BTreeMap; use std::iter; use std::vec; -use serde2::de::{self, Deserialize, Deserializer, Visitor}; +use serde::de::{self, Deserialize, Deserializer, Visitor}; #[derive(Debug)] enum Token<'a> { diff --git a/serde2/tests/test_json.rs b/tests/test_json.rs similarity index 99% rename from serde2/tests/test_json.rs rename to tests/test_json.rs index 7a2f9d63..1a7b2d62 100644 --- a/serde2/tests/test_json.rs +++ b/tests/test_json.rs @@ -1,16 +1,16 @@ #![feature(custom_derive, plugin, test)] -#![plugin(serde2_macros)] +#![plugin(serde_macros)] extern crate test; -extern crate serde2; +extern crate serde; use std::fmt::Debug; use std::collections::BTreeMap; -use serde2::de; -use serde2::ser; +use serde::de; +use serde::ser; -use serde2::json::{ +use serde::json::{ self, Value, from_str, @@ -18,7 +18,7 @@ use serde2::json::{ to_value, }; -use serde2::json::error::{Error, ErrorCode}; +use serde::json::error::{Error, ErrorCode}; macro_rules! treemap { ($($k:expr => $v:expr),*) => ({ diff --git a/serde2/tests/test_json_builder.rs b/tests/test_json_builder.rs similarity index 92% rename from serde2/tests/test_json_builder.rs rename to tests/test_json_builder.rs index 354f9440..18587b9e 100644 --- a/serde2/tests/test_json_builder.rs +++ b/tests/test_json_builder.rs @@ -1,9 +1,9 @@ -extern crate serde2; +extern crate serde; use std::collections::BTreeMap; -use serde2::json::value::Value; -use serde2::json::builder::{ArrayBuilder, ObjectBuilder}; +use serde::json::value::Value; +use serde::json::builder::{ArrayBuilder, ObjectBuilder}; #[test] fn test_array_builder() { diff --git a/serde2/tests/test_macros.rs b/tests/test_macros.rs similarity index 99% rename from serde2/tests/test_macros.rs rename to tests/test_macros.rs index 2589e5f6..b693715e 100644 --- a/serde2/tests/test_macros.rs +++ b/tests/test_macros.rs @@ -1,10 +1,10 @@ #![feature(custom_derive, plugin)] -#![plugin(serde2_macros)] +#![plugin(serde_macros)] -extern crate serde2; +extern crate serde; use std::collections::BTreeMap; -use serde2::json::{self, Value}; +use serde::json::{self, Value}; macro_rules! btreemap { () => { diff --git a/serde2/tests/test_ser.rs b/tests/test_ser.rs similarity index 99% rename from serde2/tests/test_ser.rs rename to tests/test_ser.rs index ea174515..6a36a113 100644 --- a/serde2/tests/test_ser.rs +++ b/tests/test_ser.rs @@ -1,13 +1,13 @@ #![feature(custom_derive, plugin, test)] -#![plugin(serde2_macros)] +#![plugin(serde_macros)] extern crate test; -extern crate serde2; +extern crate serde; use std::vec; use std::collections::BTreeMap; -use serde2::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor}; +use serde::ser::{Serialize, Serializer, Visitor, SeqVisitor, MapVisitor}; #[derive(Clone, PartialEq, Debug)] pub enum Token<'a> {