aboutsummaryrefslogtreecommitdiff
path: root/src/encoder
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-01-29 16:53:20 -0800
committerAlex Crichton <alex@alexcrichton.com>2017-02-08 21:21:18 -0800
commitf66d8bcf33530c858a502bfa170f2383a8cbc204 (patch)
tree76498b837fc5f1f6ba0a5f53e1b2d85c6638da4d /src/encoder
parent473908c9722eeedeec1777237a135f582faa78d8 (diff)
downloadmilf-rs-f66d8bcf33530c858a502bfa170f2383a8cbc204.tar.gz
milf-rs-f66d8bcf33530c858a502bfa170f2383a8cbc204.zip
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
Diffstat (limited to 'src/encoder')
-rw-r--r--src/encoder/mod.rs222
-rw-r--r--src/encoder/rustc_serialize.rs748
-rw-r--r--src/encoder/serde.rs339
3 files changed, 0 insertions, 1309 deletions
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<Value>),
- 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<State, Error> {
- 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<F>(&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: ::rustc_serialize::Encodable>(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: ::serde::Serialize>(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: ::rustc_serialize::Encodable>(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: ::serde::Serialize>(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<F>(&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<F>(&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<F>(&mut self, _name: &str, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- f(self)
- }
- fn emit_enum_variant<F>(&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<F>(&mut self, _a_idx: usize, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- f(self)
- }
- fn emit_enum_struct_variant<F>(&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<F>(&mut self,
- _f_name: &str,
- _f_idx: usize,
- _f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- panic!()
- }
- fn emit_struct<F>(&mut self, _name: &str, _len: usize, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- self.table(f)
- }
- fn emit_struct_field<F>(&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<F>(&mut self, len: usize, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- self.emit_seq(len, f)
- }
- fn emit_tuple_arg<F>(&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<F>(&mut self, _name: &str, _len: usize, _f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- unimplemented!()
- }
- fn emit_tuple_struct_arg<F>(&mut self, _f_idx: usize, _f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- unimplemented!()
- }
- fn emit_option<F>(&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<F>(&mut self, f: F) -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- f(self)
- }
- fn emit_seq<F>(&mut self, _len: usize, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- self.seq(f)
- }
- fn emit_seq_elt<F>(&mut self, _idx: usize, f: F)
- -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- f(self)
- }
- fn emit_map<F>(&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<F>(&mut self, _idx: usize, f: F) -> Result<(), Error>
- where F: FnOnce(&mut Encoder) -> Result<(), Error>
- {
- self.table_key(f)
- }
- fn emit_map_elt_val<F>(&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<E>(&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: rustc_serialize::Decoder>(d: &mut D) -> Result<Range10, D::Error> {
- 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<Range10, _> = Decodable::decode(&mut d_bad1);
- assert!(err1.is_err());
- let err2: Result<Range10, _> = Decodable::decode(&mut d_bad2);
- assert!(err2.is_err());
- }
-
- #[test]
- fn array() {
- #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug)]
- struct Foo { a: Vec<isize> }
-
- 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<Box<Foo>>,
- 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<String, isize>,
- set: HashSet<char>,
- }
-
- 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<Bar>, }
- #[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<Foo, DecodeError> = 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<Foo, DecodeError> = 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<String, String> }
-
- 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<String> }
-
- 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<Vec<String>> }
-
- 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<Bar> }
- #[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<String, Bar> }
- #[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<Bar> }
- #[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<Vec<Bar>> }
- #[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<Self, Error> {
- 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<V>(&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<EncoderState, Error> {
- self.serialize_seq(Some(len))
- }
-
- fn serialize_seq(&mut self, _len: Option<usize>)
- -> Result<EncoderState, Error> {
- self.seq_begin().map(|s| EncoderState { inner: s })
- }
-
- fn serialize_seq_elt<T>(&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<EncoderState, Error> {
- self.serialize_seq(Some(len))
- }
-
- fn serialize_tuple_elt<T>(&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<EncoderState, Error> {
- self.serialize_seq(Some(len))
- }
-
- fn serialize_tuple_struct_elt<T>(&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<EncoderState, Error> {
- self.serialize_seq(Some(len))
- }
-
- fn serialize_tuple_variant_elt<T>(&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<usize>) -> Result<Self, Error> {
- self.table_begin()
- }
-
- fn serialize_map_key<K>(&mut self,
- _state: &mut Encoder,
- key: K) -> Result<(), Error>
- where K: ser::Serialize
- {
- self.table_key(|me| key.serialize(me))
- }
-
- fn serialize_map_value<V>(&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, Error> {
- self.serialize_map(Some(len))
- }
-
- fn serialize_struct_elt<V>(&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, Error> {
- self.serialize_map(Some(len))
- }
-
- fn serialize_struct_variant_elt<V>(&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<T>(&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<T>(&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<E>(&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<T: Into<String>>(msg: T) -> Error {
- Error::Custom(msg.into())
- }
-}