Merge pull request #105 from dtolnay/up

Update to serde 0.8.0
This commit is contained in:
Alex Crichton 2016-07-29 09:22:22 -07:00 committed by GitHub
commit b480a26f8d
8 changed files with 510 additions and 82 deletions

View file

@ -17,7 +17,7 @@ facilitate deserializing and serializing Rust structures.
[dependencies] [dependencies]
rustc-serialize = { optional = true, version = "0.3.0" } rustc-serialize = { optional = true, version = "0.3.0" }
serde = { optional = true, version = "0.7" } serde = { optional = true, version = "0.8" }
[features] [features]
default = ["rustc-serialize"] default = ["rustc-serialize"]

93
serde-tests/Cargo.lock generated
View file

@ -2,18 +2,17 @@
name = "serde-tests" name = "serde-tests"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"serde 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_codegen 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.1.30", "toml 0.1.30",
] ]
[[package]] [[package]]
name = "aster" name = "aster"
version = "0.17.0" version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -26,13 +25,13 @@ name = "kernel32-sys"
version = "0.2.2" version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.11" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -42,20 +41,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quasi" name = "quasi"
version = "0.11.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "quasi_codegen" name = "quasi_codegen"
version = "0.11.0" version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -65,49 +66,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "serde" name = "serde"
version = "0.7.6" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "serde_codegen" name = "serde_codegen"
version = "0.7.6" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "aster 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi_codegen 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde_codegen_internals 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_codegen_internals"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syntex_errors 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "syntex" name = "syntex"
version = "0.33.0" version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"syntex_syntax 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_syntax 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntex_errors"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syntex_pos"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "syntex_syntax" name = "syntex_syntax"
version = "0.33.0" version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syntex_pos 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "term" name = "term"
version = "0.2.14" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -115,7 +150,7 @@ name = "toml"
version = "0.1.30" version = "0.1.30"
dependencies = [ dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -125,7 +160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.2.7" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]

View file

@ -5,12 +5,11 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
build = "build.rs" build = "build.rs"
[dependencies] [dependencies]
serde = "0.7" serde = "0.8"
toml = { path = "..", features = ["serde"] } toml = { path = "..", features = ["serde"] }
[build-dependencies] [build-dependencies]
syntex = "0.33" serde_codegen = "0.8"
serde_codegen = "0.7"
[lib] [lib]
name = "serde_tests" name = "serde_tests"

View file

@ -1,4 +1,3 @@
extern crate syntex;
extern crate serde_codegen; extern crate serde_codegen;
use std::env; use std::env;
@ -10,8 +9,5 @@ fn main() {
let src = Path::new("test.rs.in"); let src = Path::new("test.rs.in");
let dst = Path::new(&out_dir).join("test.rs"); let dst = Path::new(&out_dir).join("test.rs");
let mut registry = syntex::Registry::new(); serde_codegen::expand(&src, &dst).unwrap();
serde_codegen::register(&mut registry);
registry.expand("", &src, &dst).unwrap();
} }

View file

@ -1,6 +1,9 @@
use std::error; use std::error;
use std::fmt; use std::fmt;
#[cfg(feature = "rustc-serialize")]
use std::collections::{btree_map, BTreeMap}; use std::collections::{btree_map, BTreeMap};
#[cfg(feature = "rustc-serialize")]
use std::iter::Peekable; use std::iter::Peekable;
use Value; use Value;
@ -19,7 +22,9 @@ pub struct Decoder {
/// whether fields were decoded or not. /// whether fields were decoded or not.
pub toml: Option<Value>, pub toml: Option<Value>,
cur_field: Option<String>, cur_field: Option<String>,
#[cfg(feature = "rustc-serialize")]
cur_map: Peekable<btree_map::IntoIter<String, Value>>, cur_map: Peekable<btree_map::IntoIter<String, Value>>,
#[cfg(feature = "rustc-serialize")]
leftover_map: ::Table, leftover_map: ::Table,
} }
@ -115,27 +120,36 @@ impl Decoder {
/// This decoder can be passed to the `Decodable` methods or driven /// This decoder can be passed to the `Decodable` methods or driven
/// manually. /// manually.
pub fn new(toml: Value) -> Decoder { pub fn new(toml: Value) -> Decoder {
Decoder::new_empty(Some(toml), None)
}
fn sub_decoder(&self, toml: Option<Value>, field: &str) -> Decoder {
let cur_field = if field.is_empty() {
self.cur_field.clone()
} else {
match self.cur_field {
None => Some(field.to_string()),
Some(ref s) => Some(format!("{}.{}", s, field))
}
};
Decoder::new_empty(toml, cur_field)
}
#[cfg(feature = "rustc-serialize")]
fn new_empty(toml: Option<Value>, cur_field: Option<String>) -> Decoder {
Decoder { Decoder {
toml: Some(toml), toml: toml,
cur_field: None, cur_field: cur_field,
leftover_map: BTreeMap::new(), leftover_map: BTreeMap::new(),
cur_map: BTreeMap::new().into_iter().peekable(), cur_map: BTreeMap::new().into_iter().peekable(),
} }
} }
fn sub_decoder(&self, toml: Option<Value>, field: &str) -> Decoder { #[cfg(not(feature = "rustc-serialize"))]
fn new_empty(toml: Option<Value>, cur_field: Option<String>) -> Decoder {
Decoder { Decoder {
toml: toml, toml: toml,
cur_field: if field.is_empty() { cur_field: cur_field,
self.cur_field.clone()
} else {
match self.cur_field {
None => Some(field.to_string()),
Some(ref s) => Some(format!("{}.{}", s, field))
}
},
leftover_map: BTreeMap::new(),
cur_map: BTreeMap::new().into_iter().peekable(),
} }
} }

View file

@ -3,6 +3,43 @@ use Value;
use super::{Decoder, DecodeError, DecodeErrorKind}; use super::{Decoder, DecodeError, DecodeErrorKind};
use std::collections::BTreeMap; use std::collections::BTreeMap;
macro_rules! forward_to_deserialize {
($(
$name:ident ( $( $arg:ident : $ty:ty ),* );
)*) => {
$(
forward_to_deserialize!{
func: $name ( $( $arg: $ty ),* );
}
)*
};
(func: deserialize_enum ( $( $arg:ident : $ty:ty ),* );) => {
fn deserialize_enum<V>(
&mut self,
$(_: $ty,)*
_visitor: V,
) -> ::std::result::Result<V::Value, Self::Error>
where V: ::serde::de::EnumVisitor
{
Err(::serde::de::Error::invalid_type(::serde::de::Type::Enum))
}
};
(func: $name:ident ( $( $arg:ident : $ty:ty ),* );) => {
#[inline]
fn $name<V>(
&mut self,
$(_: $ty,)*
visitor: V,
) -> ::std::result::Result<V::Value, Self::Error>
where V: ::serde::de::Visitor
{
self.deserialize(visitor)
}
};
}
impl de::Deserializer for Decoder { impl de::Deserializer for Decoder {
type Error = DecodeError; type Error = DecodeError;
@ -43,6 +80,27 @@ impl de::Deserializer for Decoder {
} }
} }
fn deserialize_i8<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i16<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_i64<V>(&mut self, mut visitor: V) fn deserialize_i64<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError> -> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
@ -53,10 +111,53 @@ impl de::Deserializer for Decoder {
} }
} }
fn deserialize_u64<V>(&mut self, v: V) -> Result<V::Value, DecodeError> fn deserialize_isize<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
{ {
self.deserialize_i64(v) self.deserialize_i64(visitor)
}
fn deserialize_u8<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u16<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_u64<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_usize<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_i64(visitor)
}
fn deserialize_f32<V>(&mut self, visitor: V)
-> Result<V::Value, DecodeError>
where V: de::Visitor
{
self.deserialize_f64(visitor)
} }
fn deserialize_f64<V>(&mut self, mut visitor: V) fn deserialize_f64<V>(&mut self, mut visitor: V)
@ -79,6 +180,13 @@ impl de::Deserializer for Decoder {
} }
} }
fn deserialize_string<V>(&mut self, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor,
{
self.deserialize_str(visitor)
}
fn deserialize_char<V>(&mut self, mut visitor: V) fn deserialize_char<V>(&mut self, mut visitor: V)
-> Result<V::Value, DecodeError> -> Result<V::Value, DecodeError>
where V: de::Visitor where V: de::Visitor
@ -186,6 +294,62 @@ impl de::Deserializer for Decoder {
let mut d = <() as ValueDeserializer<Self::Error>>::into_deserializer(()); let mut d = <() as ValueDeserializer<Self::Error>>::into_deserializer(());
d.deserialize(visitor) d.deserialize(visitor)
} }
fn deserialize_bytes<V>(&mut self, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_seq_fixed_size<V>(&mut self, _len: usize, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_newtype_struct<V>(&mut self, _name: &'static str, visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(&mut self,
_name: &'static str,
_len: usize,
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
fn deserialize_struct<V>(&mut self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_map(visitor)
}
fn deserialize_tuple<V>(&mut self,
_len: usize,
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
self.deserialize_seq(visitor)
}
forward_to_deserialize!{
deserialize_unit();
deserialize_unit_struct(name: &'static str);
deserialize_struct_field();
}
} }
struct VariantVisitor { struct VariantVisitor {
@ -270,6 +434,39 @@ impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
{ {
visitor.visit_seq(self) visitor.visit_seq(self)
} }
forward_to_deserialize!{
deserialize_bool();
deserialize_usize();
deserialize_u8();
deserialize_u16();
deserialize_u32();
deserialize_u64();
deserialize_isize();
deserialize_i8();
deserialize_i16();
deserialize_i32();
deserialize_i64();
deserialize_f32();
deserialize_f64();
deserialize_char();
deserialize_str();
deserialize_string();
deserialize_unit();
deserialize_option();
deserialize_seq();
deserialize_seq_fixed_size(len: usize);
deserialize_bytes();
deserialize_map();
deserialize_unit_struct(name: &'static str);
deserialize_newtype_struct(name: &'static str);
deserialize_tuple_struct(name: &'static str, len: usize);
deserialize_struct(name: &'static str, fields: &'static [&'static str]);
deserialize_struct_field();
deserialize_tuple(len: usize);
deserialize_enum(name: &'static str, variants: &'static [&'static str]);
deserialize_ignored_any();
}
} }
impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I> impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I>
@ -492,6 +689,38 @@ impl de::Deserializer for UnitDeserializer {
{ {
visitor.visit_none() visitor.visit_none()
} }
forward_to_deserialize!{
deserialize_bool();
deserialize_usize();
deserialize_u8();
deserialize_u16();
deserialize_u32();
deserialize_u64();
deserialize_isize();
deserialize_i8();
deserialize_i16();
deserialize_i32();
deserialize_i64();
deserialize_f32();
deserialize_f64();
deserialize_char();
deserialize_str();
deserialize_string();
deserialize_unit();
deserialize_seq();
deserialize_seq_fixed_size(len: usize);
deserialize_bytes();
deserialize_map();
deserialize_unit_struct(name: &'static str);
deserialize_newtype_struct(name: &'static str);
deserialize_tuple_struct(name: &'static str, len: usize);
deserialize_struct(name: &'static str, fields: &'static [&'static str]);
deserialize_struct_field();
deserialize_tuple(len: usize);
deserialize_enum(name: &'static str, variants: &'static [&'static str]);
deserialize_ignored_any();
}
} }
impl de::Deserialize for Value { impl de::Deserialize for Value {

View file

@ -35,7 +35,7 @@ use {Value, Table};
/// assert_eq!(e.toml.get(&"foo".to_string()), Some(&Value::Integer(4))) /// assert_eq!(e.toml.get(&"foo".to_string()), Some(&Value::Integer(4)))
/// # } /// # }
/// ``` /// ```
#[derive(Default)] #[derive(Default, Debug)]
pub struct Encoder { pub struct Encoder {
/// Output TOML that is emitted. The current version of this encoder forces /// Output TOML that is emitted. The current version of this encoder forces
/// the top-level representation of a structure to be a table. /// the top-level representation of a structure to be a table.
@ -66,8 +66,9 @@ pub enum Error {
Custom(String), Custom(String),
} }
#[derive(PartialEq)] #[derive(PartialEq, Debug)]
enum State { #[doc(hidden)]
pub enum State {
Start, Start,
NextKey(String), NextKey(String),
NextArray(Vec<Value>), NextArray(Vec<Value>),
@ -112,17 +113,27 @@ impl Encoder {
} }
} }
#[cfg(feature = "rustc-serialize")]
fn seq<F>(&mut self, f: F) -> Result<(), Error> fn seq<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error> where F: FnOnce(&mut Encoder) -> Result<(), Error>
{ {
let old = mem::replace(&mut self.state, State::NextArray(Vec::new())); let old = try!(self.seq_begin());
try!(f(self)); try!(f(self));
self.seq_end(old)
}
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) { match mem::replace(&mut self.state, old) {
State::NextArray(v) => self.emit_value(Value::Array(v)), State::NextArray(v) => self.emit_value(Value::Array(v)),
_ => unreachable!(), _ => unreachable!(),
} }
} }
#[cfg(feature = "rustc-serialize")]
fn table<F>(&mut self, f: F) -> Result<(), Error> fn table<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error> where F: FnOnce(&mut Encoder) -> Result<(), Error>
{ {
@ -145,6 +156,32 @@ impl Encoder {
} }
} }
#[cfg(feature = "serde")]
fn table_begin(&mut self) -> Result<Self, Error> {
match self.state {
State::NextMapKey => Err(Error::InvalidMapKeyLocation),
_ => Ok(mem::replace(self, Encoder::new()))
}
}
#[cfg(feature = "serde")]
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(())
}
fn table_key<F>(&mut self, f: F) -> Result<(), Error> fn table_key<F>(&mut self, f: F) -> Result<(), Error>
where F: FnOnce(&mut Encoder) -> Result<(), Error> where F: FnOnce(&mut Encoder) -> Result<(), Error>
{ {

View file

@ -1,9 +1,16 @@
use serde::ser; use serde::ser;
use Value; use Value;
use super::{Encoder, Error}; use super::{Encoder, Error, State};
impl ser::Serializer for Encoder { impl ser::Serializer for Encoder {
type Error = Error; type Error = Error;
type MapState = Self;
type StructState = Self;
type StructVariantState = Self;
type SeqState = State;
type TupleState = State;
type TupleStructState = State;
type TupleVariantState = State;
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> { fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
self.emit_value(Value::Boolean(v)) self.emit_value(Value::Boolean(v))
@ -14,12 +21,42 @@ impl ser::Serializer for Encoder {
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> { fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
self.serialize_i64(v as i64) 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> { fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
self.emit_value(Value::Float(v)) self.emit_value(Value::Float(v))
} }
fn serialize_str(&mut self, value: &str) -> Result<(), Error> { fn serialize_str(&mut self, value: &str) -> Result<(), Error> {
self.emit_value(Value::String(value.to_string())) 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> { fn serialize_unit(&mut self) -> Result<(), Error> {
Ok(()) Ok(())
} }
@ -34,33 +71,99 @@ impl ser::Serializer for Encoder {
{ {
value.serialize(self) value.serialize(self)
} }
fn serialize_seq<V>(&mut self, mut visitor: V) -> Result<(), Error> fn serialize_bytes(&mut self, v: &[u8]) -> Result<(), Error> {
where V: ser::SeqVisitor let mut state = try!(self.serialize_seq(Some(v.len())));
{ for c in v {
self.seq(|me| { try!(self.serialize_seq_elt(&mut state, c));
while try!(visitor.visit(me)).is_some() {} }
Ok(()) self.serialize_seq_end(state)
})
} }
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Error> fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<State, Error> {
self.serialize_seq(Some(len))
}
fn serialize_seq(&mut self, _len: Option<usize>) -> Result<State, Error> {
self.seq_begin()
}
fn serialize_seq_elt<T>(&mut self, _state: &mut State, value: T) -> Result<(), Error>
where T: ser::Serialize where T: ser::Serialize
{ {
value.serialize(self) value.serialize(self)
} }
fn serialize_map<V>(&mut self, mut visitor: V) -> Result<(), Error> fn serialize_seq_end(&mut self, state: State) -> Result<(), Error> {
where V: ser::MapVisitor self.seq_end(state)
{
self.table(|me| {
while try!(visitor.visit(me)).is_some() {}
Ok(())
})
} }
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Error> fn serialize_tuple(&mut self, len: usize) -> Result<State, Error> {
where K: ser::Serialize, V: ser::Serialize self.serialize_seq(Some(len))
}
fn serialize_tuple_elt<T>(&mut self, state: &mut State, value: T) -> Result<(), Error>
where T: ser::Serialize
{ {
try!(self.table_key(|me| key.serialize(me))); self.serialize_seq_elt(state, value)
try!(value.serialize(self)); }
Ok(()) fn serialize_tuple_end(&mut self, state: State) -> Result<(), Error> {
self.serialize_seq_end(state)
}
fn serialize_tuple_struct(&mut self, _name: &'static str, len: usize) -> Result<State, Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct_elt<T>(&mut self, state: &mut State, value: T) -> Result<(), Error>
where T: ser::Serialize
{
self.serialize_seq_elt(state, value)
}
fn serialize_tuple_struct_end(&mut self, state: State) -> Result<(), Error> {
self.serialize_seq_end(state)
}
fn serialize_tuple_variant(&mut self, _name: &'static str, _id: usize, _variant: &'static str, len: usize) -> Result<State, Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant_elt<T>(&mut self, state: &mut State, value: T) -> Result<(), Error>
where T: ser::Serialize
{
self.serialize_seq_elt(state, value)
}
fn serialize_tuple_variant_end(&mut self, state: State) -> 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, fn serialize_newtype_struct<T>(&mut self,
_name: &'static str, _name: &'static str,
@ -80,6 +183,14 @@ impl ser::Serializer for Encoder {
// Don't serialize the newtype struct variant in a tuple. // Don't serialize the newtype struct variant in a tuple.
value.serialize(self) 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 { impl ser::Serialize for Value {
@ -93,12 +204,19 @@ impl ser::Serialize for Value {
Value::Boolean(b) => e.serialize_bool(b), Value::Boolean(b) => e.serialize_bool(b),
Value::Datetime(ref s) => e.serialize_str(s), Value::Datetime(ref s) => e.serialize_str(s),
Value::Array(ref a) => { Value::Array(ref a) => {
e.serialize_seq(ser::impls::SeqIteratorVisitor::new(a.iter(), let mut state = try!(e.serialize_seq(Some(a.len())));
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) => { Value::Table(ref t) => {
e.serialize_map(ser::impls::MapIteratorVisitor::new(t.iter(), let mut state = try!(e.serialize_map(Some(t.len())));
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)
} }
} }
} }