From f66d8bcf33530c858a502bfa170f2383a8cbc204 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 29 Jan 2017 16:53:20 -0800 Subject: Rewrite crate with serde support from ground up This commit completely rewrites this crate from the ground up, supporting serde at the lowest levels as I believe serde support was intended to do. This is a major change from the previous versions of this crate, with a summary of changes being: * Serialization directly to TOML is now supported without going through a `Value` first. * Deserialization directly from TOML is now supported without going through a `Value`. Note that due to the TOML format some values still are buffered in intermediate memory, but overall this should be at a minimum now. * The API of `Value` was overhauled to match the API of `serde_json::Value`. The changes here were to: * Add `is_*` accessors * Add `get` and `get_mut` for one-field lookups. * Implement panicking lookups through `Index` The old `index` methods are now gone in favor of `get` and `Index` implementations. * A `Datetime` type has been added to represent a TOML datetime in a first-class fashion. Currently this type provides no accessors other than a `Display` implementation, but the idea is that this will grow support over time for decomposing the date. * Support for the `rustc-serialize` crate has been dropped, that'll stay on the 0.2 and 0.1 release trains. * This crate no longer supports the detection of unused fields, for that though you can use the `serde_ignored` crate on crates.io --- src/encoder/mod.rs | 222 ------------ src/encoder/rustc_serialize.rs | 748 ----------------------------------------- src/encoder/serde.rs | 339 ------------------- 3 files changed, 1309 deletions(-) delete mode 100644 src/encoder/mod.rs delete mode 100644 src/encoder/rustc_serialize.rs delete mode 100644 src/encoder/serde.rs (limited to 'src/encoder') diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs deleted file mode 100644 index 910c970..0000000 --- a/src/encoder/mod.rs +++ /dev/null @@ -1,222 +0,0 @@ -use std::collections::BTreeMap; -use std::error; -use std::fmt; -use std::mem; - -use {Value, Table}; - -#[cfg(feature = "rustc-serialize")] mod rustc_serialize; -#[cfg(feature = "serde")] mod serde; - -/// A structure to transform Rust values into TOML values. -/// -/// This encoder implements the serialization `Encoder` interface, allowing -/// `Encodable` rust types to be fed into the encoder. The output of this -/// encoder is a TOML `Table` structure. The resulting TOML can be stringified -/// if necessary. -/// -/// # Example -/// -/// ``` -/// extern crate rustc_serialize; -/// extern crate toml; -/// -/// # fn main() { -/// use toml::{Encoder, Value}; -/// use rustc_serialize::Encodable; -/// -/// #[derive(RustcEncodable)] -/// struct MyStruct { foo: isize, bar: String } -/// let my_struct = MyStruct { foo: 4, bar: "hello!".to_string() }; -/// -/// let mut e = Encoder::new(); -/// my_struct.encode(&mut e).unwrap(); -/// -/// assert_eq!(e.toml.get(&"foo".to_string()), Some(&Value::Integer(4))) -/// # } -/// ``` -#[derive(Default, Debug)] -pub struct Encoder { - /// Output TOML that is emitted. The current version of this encoder forces - /// the top-level representation of a structure to be a table. - /// - /// This field can be used to extract the return value after feeding a value - /// into this `Encoder`. - pub toml: Table, - state: State, -} - -/// Enumeration of errors which can occur while encoding a rust value into a -/// TOML value. -#[allow(missing_copy_implementations)] -#[derive(Debug)] -pub enum Error { - /// Indication that a key was needed when a value was emitted, but no key - /// was previously emitted. - NeedsKey, - /// Indication that a key was emitted, but no value was emitted. - NoValue, - /// Indicates that a map key was attempted to be emitted at an invalid - /// location. - InvalidMapKeyLocation, - /// Indicates that a type other than a string was attempted to be used as a - /// map key type. - InvalidMapKeyType, - /// An error returned whenever a `NaN` value for a float is attempted to be - /// encoded - NanEncoded, - /// An error returned whenever an infinity value for a float is attempted to - /// be encoded - InfinityEncoded, - /// A custom error type was generated - Custom(String), -} - -/// Internal state of the encoder when encoding transitions -#[derive(Debug)] -pub struct EncoderState { - inner: State, -} - -#[derive(PartialEq, Debug)] -enum State { - Start, - NextKey(String), - NextArray(Vec), - NextMapKey, -} - -impl Default for State { - fn default() -> State { State::Start } -} - -impl Encoder { - /// Constructs a new encoder which will emit to the given output stream. - pub fn new() -> Encoder { - Encoder { state: State::Start, toml: BTreeMap::new() } - } - - fn emit_value(&mut self, v: Value) -> Result<(), Error> { - match v { - Value::Float(f) => { - if f.is_nan() { - return Err(Error::NanEncoded) - } - if f.is_infinite() { - return Err(Error::InfinityEncoded) - } - } - _ => {} - } - match mem::replace(&mut self.state, State::Start) { - State::NextKey(key) => { self.toml.insert(key, v); Ok(()) } - State::NextArray(mut vec) => { - // TODO: validate types - vec.push(v); - self.state = State::NextArray(vec); - Ok(()) - } - State::NextMapKey => { - match v { - Value::String(s) => { self.state = State::NextKey(s); Ok(()) } - _ => Err(Error::InvalidMapKeyType) - } - } - _ => Err(Error::NeedsKey) - } - } - - fn emit_none(&mut self) -> Result<(), Error> { - match mem::replace(&mut self.state, State::Start) { - State::Start => unreachable!(), - State::NextKey(_) => Ok(()), - State::NextArray(..) => panic!("how to encode None in an array?"), - State::NextMapKey => Err(Error::InvalidMapKeyLocation), - } - } - - fn seq_begin(&mut self) -> Result { - Ok(mem::replace(&mut self.state, State::NextArray(Vec::new()))) - } - - fn seq_end(&mut self, old: State) -> Result<(), Error> { - match mem::replace(&mut self.state, old) { - State::NextArray(v) => self.emit_value(Value::Array(v)), - _ => unreachable!(), - } - } - - fn table_key(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - match mem::replace(&mut self.state, State::NextMapKey) { - State::Start => {} - _ => return Err(Error::InvalidMapKeyLocation), - } - try!(f(self)); - match self.state { - State::NextKey(_) => Ok(()), - _ => Err(Error::InvalidMapKeyLocation), - } - } -} - -/// Encodes an encodable value into a TOML value. -/// -/// This function expects the type given to represent a TOML table in some form. -/// If encoding encounters an error, then this function will fail the task. -#[cfg(feature = "rustc-serialize")] -pub fn encode(t: &T) -> Value { - let mut e = Encoder::new(); - t.encode(&mut e).unwrap(); - Value::Table(e.toml) -} - -/// Encodes an encodable value into a TOML value. -/// -/// This function expects the type given to represent a TOML table in some form. -/// If encoding encounters an error, then this function will fail the task. -#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))] -pub fn encode(t: &T) -> Value { - let mut e = Encoder::new(); - t.serialize(&mut e).unwrap(); - Value::Table(e.toml) -} - -/// Encodes an encodable value into a TOML string. -/// -/// This function expects the type given to represent a TOML table in some form. -/// If encoding encounters an error, then this function will fail the task. -#[cfg(feature = "rustc-serialize")] -pub fn encode_str(t: &T) -> String { - encode(t).to_string() -} - -/// Encodes an encodable value into a TOML string. -/// -/// This function expects the type given to represent a TOML table in some form. -/// If encoding encounters an error, then this function will fail the task. -#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))] -pub fn encode_str(t: &T) -> String { - encode(t).to_string() -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Error::NeedsKey => write!(f, "need a key to encode"), - Error::NoValue => write!(f, "no value to emit for a previous key"), - Error::InvalidMapKeyLocation => write!(f, "a map cannot be emitted \ - at this location"), - Error::InvalidMapKeyType => write!(f, "only strings can be used as \ - key types"), - Error::NanEncoded => write!(f, "cannot encode NaN"), - Error::InfinityEncoded => write!(f, "cannot encode infinity"), - Error::Custom(ref s) => write!(f, "custom error: {}", s), - } - } -} - -impl error::Error for Error { - fn description(&self) -> &str { "TOML encoding error" } -} diff --git a/src/encoder/rustc_serialize.rs b/src/encoder/rustc_serialize.rs deleted file mode 100644 index 0eda740..0000000 --- a/src/encoder/rustc_serialize.rs +++ /dev/null @@ -1,748 +0,0 @@ -use std::mem; - -use rustc_serialize; -use Value; -use super::{Encoder, Error, State}; -use super::Error::*; - -impl Encoder { - fn table(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - match mem::replace(&mut self.state, State::Start) { - State::NextKey(key) => { - let mut nested = Encoder::new(); - try!(f(&mut nested)); - self.toml.insert(key, Value::Table(nested.toml)); - Ok(()) - } - State::NextArray(mut arr) => { - let mut nested = Encoder::new(); - try!(f(&mut nested)); - arr.push(Value::Table(nested.toml)); - self.state = State::NextArray(arr); - Ok(()) - } - State::Start => f(self), - State::NextMapKey => Err(Error::InvalidMapKeyLocation), - } - } - - fn seq(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - let old = try!(self.seq_begin()); - try!(f(self)); - self.seq_end(old) - } -} - -impl rustc_serialize::Encoder for Encoder { - type Error = Error; - - fn emit_nil(&mut self) -> Result<(), Error> { Ok(()) } - fn emit_usize(&mut self, v: usize) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_u8(&mut self, v: u8) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_u16(&mut self, v: u16) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_u32(&mut self, v: u32) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_u64(&mut self, v: u64) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_isize(&mut self, v: isize) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_i8(&mut self, v: i8) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_i16(&mut self, v: i16) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_i32(&mut self, v: i32) -> Result<(), Error> { - self.emit_i64(v as i64) - } - fn emit_i64(&mut self, v: i64) -> Result<(), Error> { - self.emit_value(Value::Integer(v)) - } - fn emit_bool(&mut self, v: bool) -> Result<(), Error> { - self.emit_value(Value::Boolean(v)) - } - fn emit_f32(&mut self, v: f32) -> Result<(), Error> { self.emit_f64(v as f64) } - fn emit_f64(&mut self, v: f64) -> Result<(), Error> { - self.emit_value(Value::Float(v)) - } - fn emit_char(&mut self, v: char) -> Result<(), Error> { - self.emit_str(&v.to_string()) - } - fn emit_str(&mut self, v: &str) -> Result<(), Error> { - self.emit_value(Value::String(v.to_string())) - } - fn emit_enum(&mut self, _name: &str, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_enum_variant(&mut self, _v_name: &str, _v_id: usize, - _len: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_enum_variant_arg(&mut self, _a_idx: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_enum_struct_variant(&mut self, _v_name: &str, _v_id: usize, - _len: usize, - _f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - panic!() - } - fn emit_enum_struct_variant_field(&mut self, - _f_name: &str, - _f_idx: usize, - _f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - panic!() - } - fn emit_struct(&mut self, _name: &str, _len: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.table(f) - } - fn emit_struct_field(&mut self, f_name: &str, _f_idx: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - let old = mem::replace(&mut self.state, - State::NextKey(f_name.to_string())); - try!(f(self)); - if self.state != State::Start { - return Err(NoValue) - } - self.state = old; - Ok(()) - } - fn emit_tuple(&mut self, len: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.emit_seq_elt(idx, f) - } - fn emit_tuple_struct(&mut self, _name: &str, _len: usize, _f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - unimplemented!() - } - fn emit_tuple_struct_arg(&mut self, _f_idx: usize, _f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - unimplemented!() - } - fn emit_option(&mut self, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_option_none(&mut self) -> Result<(), Error> { - self.emit_none() - } - fn emit_option_some(&mut self, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_seq(&mut self, _len: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.seq(f) - } - fn emit_seq_elt(&mut self, _idx: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } - fn emit_map(&mut self, len: usize, f: F) - -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.emit_struct("foo", len, f) - } - fn emit_map_elt_key(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - self.table_key(f) - } - fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> Result<(), Error> - where F: FnOnce(&mut Encoder) -> Result<(), Error> - { - f(self) - } -} - -impl rustc_serialize::Encodable for Value { - fn encode(&self, e: &mut E) -> Result<(), E::Error> - where E: rustc_serialize::Encoder - { - match *self { - Value::String(ref s) => e.emit_str(s), - Value::Integer(i) => e.emit_i64(i), - Value::Float(f) => e.emit_f64(f), - Value::Boolean(b) => e.emit_bool(b), - Value::Datetime(ref s) => e.emit_str(s), - Value::Array(ref a) => { - e.emit_seq(a.len(), |e| { - for item in a { - try!(item.encode(e)); - } - Ok(()) - }) - } - Value::Table(ref t) => { - e.emit_map(t.len(), |e| { - for (i, (key, value)) in t.iter().enumerate() { - try!(e.emit_map_elt_key(i, |e| e.emit_str(key))); - try!(e.emit_map_elt_val(i, |e| value.encode(e))); - } - Ok(()) - }) - } - } - } -} - -#[cfg(test)] -mod tests { - use std::collections::{BTreeMap, HashSet}; - use rustc_serialize::{self, Encodable, Decodable}; - - use {Encoder, Decoder, DecodeError}; - use Value; - use Value::{Table, Integer, Array, Float}; - - macro_rules! encode( ($t:expr) => ({ - let mut e = Encoder::new(); - $t.encode(&mut e).unwrap(); - e.toml - }) ); - - macro_rules! decode( ($t:expr) => ({ - let mut d = Decoder::new($t); - Decodable::decode(&mut d).unwrap() - }) ); - - macro_rules! map( ($($k:ident, $v:expr),*) => ({ - let mut _m = BTreeMap::new(); - $(_m.insert(stringify!($k).to_string(), $v);)* - _m - }) ); - - #[test] - fn smoke() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: isize } - - let v = Foo { a: 2 }; - assert_eq!(encode!(v), map! { a, Integer(2) }); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn smoke_hyphen() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a_b: isize } - - let v = Foo { a_b: 2 }; - assert_eq!(encode!(v), map! { a_b, Integer(2) }); - assert_eq!(v, decode!(Table(encode!(v)))); - - let mut m = BTreeMap::new(); - m.insert("a-b".to_string(), Integer(2)); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn nested() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: isize, b: Bar } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: String } - - let v = Foo { a: 2, b: Bar { a: "test".to_string() } }; - assert_eq!(encode!(v), - map! { - a, Integer(2), - b, Table(map! { - a, Value::String("test".to_string()) - }) - }); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn application_decode_error() { - #[derive(PartialEq, Debug)] - struct Range10(usize); - impl Decodable for Range10 { - fn decode(d: &mut D) -> Result { - let x: usize = try!(Decodable::decode(d)); - if x > 10 { - Err(d.error("Value out of range!")) - } else { - Ok(Range10(x)) - } - } - } - let mut d_good = Decoder::new(Integer(5)); - let mut d_bad1 = Decoder::new(Value::String("not an isize".to_string())); - let mut d_bad2 = Decoder::new(Integer(11)); - - assert_eq!(Ok(Range10(5)), Decodable::decode(&mut d_good)); - - let err1: Result = Decodable::decode(&mut d_bad1); - assert!(err1.is_err()); - let err2: Result = Decodable::decode(&mut d_bad2); - assert!(err2.is_err()); - } - - #[test] - fn array() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Vec } - - let v = Foo { a: vec![1, 2, 3, 4] }; - assert_eq!(encode!(v), - map! { - a, Array(vec![ - Integer(1), - Integer(2), - Integer(3), - Integer(4) - ]) - }); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn tuple() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: (isize, isize, isize, isize) } - - let v = Foo { a: (1, 2, 3, 4) }; - assert_eq!(encode!(v), - map! { - a, Array(vec![ - Integer(1), - Integer(2), - Integer(3), - Integer(4) - ]) - }); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn inner_structs_with_options() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { - a: Option>, - b: Bar, - } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { - a: String, - b: f64, - } - - let v = Foo { - a: Some(Box::new(Foo { - a: None, - b: Bar { a: "foo".to_string(), b: 4.5 }, - })), - b: Bar { a: "bar".to_string(), b: 1.0 }, - }; - assert_eq!(encode!(v), - map! { - a, Table(map! { - b, Table(map! { - a, Value::String("foo".to_string()), - b, Float(4.5) - }) - }), - b, Table(map! { - a, Value::String("bar".to_string()), - b, Float(1.0) - }) - }); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn hashmap() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { - map: BTreeMap, - set: HashSet, - } - - let v = Foo { - map: { - let mut m = BTreeMap::new(); - m.insert("foo".to_string(), 10); - m.insert("bar".to_string(), 4); - m - }, - set: { - let mut s = HashSet::new(); - s.insert('a'); - s - }, - }; - assert_eq!(encode!(v), - map! { - map, Table(map! { - foo, Integer(10), - bar, Integer(4) - }), - set, Array(vec![Value::String("a".to_string())]) - } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn tuple_struct() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo(isize, String, f64); - - let v = Foo(1, "foo".to_string(), 4.5); - assert_eq!( - encode!(v), - map! { - _field0, Integer(1), - _field1, Value::String("foo".to_string()), - _field2, Float(4.5) - } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn table_array() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Vec, } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: isize } - - let v = Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] }; - assert_eq!( - encode!(v), - map! { - a, Array(vec![ - Table(map!{ a, Integer(1) }), - Table(map!{ a, Integer(2) }), - ]) - } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn type_errors() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { bar: isize } - - let mut d = Decoder::new(Table(map! { - bar, Float(1.0) - })); - let a: Result = Decodable::decode(&mut d); - match a { - Ok(..) => panic!("should not have decoded"), - Err(e) => { - assert_eq!(e.to_string(), - "expected a value of type `integer`, but \ - found a value of type `float` for the key `bar`"); - } - } - } - - #[test] - fn missing_errors() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { bar: isize } - - let mut d = Decoder::new(Table(map! { - })); - let a: Result = Decodable::decode(&mut d); - match a { - Ok(..) => panic!("should not have decoded"), - Err(e) => { - assert_eq!(e.to_string(), - "expected a value of type `integer` for the key `bar`"); - } - } - } - - #[test] - fn parse_enum() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: E } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - enum E { - Bar(isize), - Baz(f64), - Last(Foo2), - } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo2 { - test: String, - } - - let v = Foo { a: E::Bar(10) }; - assert_eq!( - encode!(v), - map! { a, Integer(10) } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - - let v = Foo { a: E::Baz(10.2) }; - assert_eq!( - encode!(v), - map! { a, Float(10.2) } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - - let v = Foo { a: E::Last(Foo2 { test: "test".to_string() }) }; - assert_eq!( - encode!(v), - map! { a, Table(map! { test, Value::String("test".to_string()) }) } - ); - assert_eq!(v, decode!(Table(encode!(v)))); - } - - #[test] - fn unused_fields() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: isize } - - let v = Foo { a: 2 }; - let mut d = Decoder::new(Table(map! { - a, Integer(2), - b, Integer(5) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, Some(Table(map! { - b, Integer(5) - }))); - } - - #[test] - fn unused_fields2() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Bar } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: isize } - - let v = Foo { a: Bar { a: 2 } }; - let mut d = Decoder::new(Table(map! { - a, Table(map! { - a, Integer(2), - b, Integer(5) - }) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, Some(Table(map! { - a, Table(map! { - b, Integer(5) - }) - }))); - } - - #[test] - fn unused_fields3() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Bar } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: isize } - - let v = Foo { a: Bar { a: 2 } }; - let mut d = Decoder::new(Table(map! { - a, Table(map! { - a, Integer(2) - }) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, None); - } - - #[test] - fn unused_fields4() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: BTreeMap } - - let v = Foo { a: map! { a, "foo".to_string() } }; - let mut d = Decoder::new(Table(map! { - a, Table(map! { - a, Value::String("foo".to_string()) - }) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, None); - } - - #[test] - fn unused_fields5() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Vec } - - let v = Foo { a: vec!["a".to_string()] }; - let mut d = Decoder::new(Table(map! { - a, Array(vec![Value::String("a".to_string())]) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, None); - } - - #[test] - fn unused_fields6() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Option> } - - let v = Foo { a: Some(vec![]) }; - let mut d = Decoder::new(Table(map! { - a, Array(vec![]) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, None); - } - - #[test] - fn unused_fields7() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Vec } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: isize } - - let v = Foo { a: vec![Bar { a: 1 }] }; - let mut d = Decoder::new(Table(map! { - a, Array(vec![Table(map! { - a, Integer(1), - b, Integer(2) - })]) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, Some(Table(map! { - a, Array(vec![Table(map! { - b, Integer(2) - })]) - }))); - } - - #[test] - fn unused_fields8() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: BTreeMap } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar { a: isize } - - let v = Foo { a: map! { a, Bar { a: 2 } } }; - let mut d = Decoder::new(Table(map! { - a, Table(map! { - a, Table(map! { - a, Integer(2), - b, Integer(2) - }) - }) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - assert_eq!(d.toml, Some(Table(map! { - a, Table(map! { - a, Table(map! { - b, Integer(2) - }) - }) - }))); - } - - #[test] - fn empty_arrays() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Vec } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar; - - let v = Foo { a: vec![] }; - let mut d = Decoder::new(Table(map! {})); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - } - - #[test] - fn empty_arrays2() { - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Foo { a: Option> } - #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)] - struct Bar; - - let v = Foo { a: None }; - let mut d = Decoder::new(Table(map! {})); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - - let v = Foo { a: Some(vec![]) }; - let mut d = Decoder::new(Table(map! { - a, Array(vec![]) - })); - assert_eq!(v, Decodable::decode(&mut d).unwrap()); - } - - #[test] - fn round_trip() { - let toml = r#" - [test] - foo = "bar" - - [[values]] - foo = "baz" - - [[values]] - foo = "qux" - "#; - - let value: Value = toml.parse().unwrap(); - let val2 = ::encode_str(&value).parse().unwrap(); - assert_eq!(value, val2); - } -} diff --git a/src/encoder/serde.rs b/src/encoder/serde.rs deleted file mode 100644 index 997bc37..0000000 --- a/src/encoder/serde.rs +++ /dev/null @@ -1,339 +0,0 @@ -use std::mem; - -use serde::ser; -use Value; -use super::{Encoder, Error, EncoderState, State}; - -impl Encoder { - fn table_begin(&mut self) -> Result { - match self.state { - State::NextMapKey => Err(Error::InvalidMapKeyLocation), - _ => Ok(mem::replace(self, Encoder::new())) - } - } - - fn table_end(&mut self, mut state: Self) -> Result<(), Error> { - match state.state { - State::NextKey(key) => { - mem::swap(&mut self.toml, &mut state.toml); - self.toml.insert(key, Value::Table(state.toml)); - }, - State::NextArray(mut arr) => { - mem::swap(&mut self.toml, &mut state.toml); - arr.push(Value::Table(state.toml)); - self.state = State::NextArray(arr); - }, - State::Start => {}, - State::NextMapKey => unreachable!(), - } - Ok(()) - } -} - -impl ser::Serializer for Encoder { - type Error = Error; - type MapState = Self; - type StructState = Self; - type StructVariantState = Self; - type SeqState = EncoderState; - type TupleState = EncoderState; - type TupleStructState = EncoderState; - type TupleVariantState = EncoderState; - - fn serialize_bool(&mut self, v: bool) -> Result<(), Error> { - self.emit_value(Value::Boolean(v)) - } - - fn serialize_i64(&mut self, v: i64) -> Result<(), Error> { - self.emit_value(Value::Integer(v)) - } - - // TODO: checked casts - - fn serialize_u64(&mut self, v: u64) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_isize(&mut self, v: isize) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_usize(&mut self, v: usize) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_i8(&mut self, v: i8) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_u8(&mut self, v: u8) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_i16(&mut self, v: i16) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_u16(&mut self, v: u16) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_i32(&mut self, v: i32) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_u32(&mut self, v: u32) -> Result<(), Error> { - self.serialize_i64(v as i64) - } - - fn serialize_f32(&mut self, v: f32) -> Result<(), Error> { - self.serialize_f64(v as f64) - } - - fn serialize_f64(&mut self, v: f64) -> Result<(), Error> { - self.emit_value(Value::Float(v)) - } - - fn serialize_str(&mut self, value: &str) -> Result<(), Error> { - self.emit_value(Value::String(value.to_string())) - } - - fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Error> { - Ok(()) - } - - fn serialize_unit(&mut self) -> Result<(), Error> { - Ok(()) - } - - fn serialize_none(&mut self) -> Result<(), Error> { - self.emit_none() - } - - fn serialize_char(&mut self, c: char) -> Result<(), Error> { - self.serialize_str(&c.to_string()) - } - - fn serialize_some(&mut self, value: V) -> Result<(), Error> - where V: ser::Serialize - { - value.serialize(self) - } - - fn serialize_bytes(&mut self, v: &[u8]) -> Result<(), Error> { - let mut state = try!(self.serialize_seq(Some(v.len()))); - for c in v { - try!(self.serialize_seq_elt(&mut state, c)); - } - self.serialize_seq_end(state) - } - - fn serialize_seq_fixed_size(&mut self, len: usize) - -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_seq(&mut self, _len: Option) - -> Result { - self.seq_begin().map(|s| EncoderState { inner: s }) - } - - fn serialize_seq_elt(&mut self, - _state: &mut EncoderState, - value: T) -> Result<(), Error> - where T: ser::Serialize - { - value.serialize(self) - } - - fn serialize_seq_end(&mut self, state: EncoderState) -> Result<(), Error> { - self.seq_end(state.inner) - } - - fn serialize_tuple(&mut self, len: usize) - -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_elt(&mut self, - state: &mut EncoderState, - value: T) -> Result<(), Error> - where T: ser::Serialize - { - self.serialize_seq_elt(state, value) - } - - fn serialize_tuple_end(&mut self, state: EncoderState) -> Result<(), Error> { - self.serialize_seq_end(state) - } - - fn serialize_tuple_struct(&mut self, - _name: &'static str, - len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_struct_elt(&mut self, - state: &mut EncoderState, - value: T) -> Result<(), Error> - where T: ser::Serialize - { - self.serialize_seq_elt(state, value) - } - - fn serialize_tuple_struct_end(&mut self, state: EncoderState) - -> Result<(), Error> { - self.serialize_seq_end(state) - } - - fn serialize_tuple_variant(&mut self, - _name: &'static str, - _id: usize, - _variant: &'static str, - len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_variant_elt(&mut self, - state: &mut EncoderState, - value: T) -> Result<(), Error> - where T: ser::Serialize - { - self.serialize_seq_elt(state, value) - } - - fn serialize_tuple_variant_end(&mut self, state: EncoderState) - -> Result<(), Error> { - self.serialize_seq_end(state) - } - - fn serialize_map(&mut self, _len: Option) -> Result { - self.table_begin() - } - - fn serialize_map_key(&mut self, - _state: &mut Encoder, - key: K) -> Result<(), Error> - where K: ser::Serialize - { - self.table_key(|me| key.serialize(me)) - } - - fn serialize_map_value(&mut self, - _state: &mut Encoder, - value: V) -> Result<(), Error> - where V: ser::Serialize - { - value.serialize(self) - } - - fn serialize_map_end(&mut self, state: Self) -> Result<(), Error> { - self.table_end(state) - } - - fn serialize_struct(&mut self, - _name: &'static str, - len: usize) -> Result { - self.serialize_map(Some(len)) - } - - fn serialize_struct_elt(&mut self, - state: &mut Encoder, - key: &'static str, - value: V) -> Result<(), Error> - where V: ser::Serialize - { - try!(self.serialize_map_key(state, key)); - self.serialize_map_value(state, value) - } - - fn serialize_struct_end(&mut self, state: Self) -> Result<(), Error> { - self.serialize_map_end(state) - } - - fn serialize_struct_variant(&mut self, - _name: &'static str, - _id: usize, - _variant: &'static str, - len: usize) -> Result { - self.serialize_map(Some(len)) - } - - fn serialize_struct_variant_elt(&mut self, - state: &mut Encoder, - key: &'static str, - value: V) -> Result<(), Error> - where V: ser::Serialize - { - try!(self.serialize_map_key(state, key)); - self.serialize_map_value(state, value) - } - - fn serialize_struct_variant_end(&mut self, state: Self) -> Result<(), Error> { - self.serialize_map_end(state) - } - - fn serialize_newtype_struct(&mut self, - _name: &'static str, - value: T) -> Result<(), Self::Error> - where T: ser::Serialize, - { - // Don't serialize the newtype struct in a tuple. - value.serialize(self) - } - - fn serialize_newtype_variant(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - value: T) -> Result<(), Self::Error> - where T: ser::Serialize, - { - // Don't serialize the newtype struct variant in a tuple. - value.serialize(self) - } - - fn serialize_unit_variant(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - ) -> Result<(), Self::Error> - { - Ok(()) - } -} - -impl ser::Serialize for Value { - fn serialize(&self, e: &mut E) -> Result<(), E::Error> - where E: ser::Serializer - { - match *self { - Value::String(ref s) => e.serialize_str(s), - Value::Integer(i) => e.serialize_i64(i), - Value::Float(f) => e.serialize_f64(f), - Value::Boolean(b) => e.serialize_bool(b), - Value::Datetime(ref s) => e.serialize_str(s), - Value::Array(ref a) => { - let mut state = try!(e.serialize_seq(Some(a.len()))); - for el in a.iter() { - try!(e.serialize_seq_elt(&mut state, el)); - } - e.serialize_seq_end(state) - } - Value::Table(ref t) => { - let mut state = try!(e.serialize_map(Some(t.len()))); - for (k, v) in t.iter() { - try!(e.serialize_map_key(&mut state, k)); - try!(e.serialize_map_value(&mut state, v)); - } - e.serialize_map_end(state) - } - } - } -} - -impl ser::Error for Error { - fn custom>(msg: T) -> Error { - Error::Custom(msg.into()) - } -} -- cgit v1.2.3