commit
b480a26f8d
|
@ -17,7 +17,7 @@ facilitate deserializing and serializing Rust structures.
|
|||
|
||||
[dependencies]
|
||||
rustc-serialize = { optional = true, version = "0.3.0" }
|
||||
serde = { optional = true, version = "0.7" }
|
||||
serde = { optional = true, version = "0.8" }
|
||||
|
||||
[features]
|
||||
default = ["rustc-serialize"]
|
||||
|
|
93
serde-tests/Cargo.lock
generated
93
serde-tests/Cargo.lock
generated
|
@ -2,18 +2,17 @@
|
|||
name = "serde-tests"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (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.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.1.30",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aster"
|
||||
version = "0.17.0"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
|
@ -26,13 +25,13 @@ name = "kernel32-sys"
|
|||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.11"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -42,20 +41,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "quasi"
|
||||
version = "0.11.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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 = "quasi_codegen"
|
||||
version = "0.11.0"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.33.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.39.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]]
|
||||
|
@ -65,49 +66,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.7.6"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_codegen"
|
||||
version = "0.7.6"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syntex_syntax 0.33.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.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quasi_codegen 0.16.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 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]]
|
||||
name = "syntex"
|
||||
version = "0.33.0"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "syntex_syntax"
|
||||
version = "0.33.0"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"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)",
|
||||
"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)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.2.14"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"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]]
|
||||
|
@ -115,7 +150,7 @@ name = "toml"
|
|||
version = "0.1.30"
|
||||
dependencies = [
|
||||
"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]]
|
||||
|
@ -125,7 +160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.7"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -5,12 +5,11 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
|||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
serde = "0.7"
|
||||
serde = "0.8"
|
||||
toml = { path = "..", features = ["serde"] }
|
||||
|
||||
[build-dependencies]
|
||||
syntex = "0.33"
|
||||
serde_codegen = "0.7"
|
||||
serde_codegen = "0.8"
|
||||
|
||||
[lib]
|
||||
name = "serde_tests"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
extern crate syntex;
|
||||
extern crate serde_codegen;
|
||||
|
||||
use std::env;
|
||||
|
@ -10,8 +9,5 @@ fn main() {
|
|||
let src = Path::new("test.rs.in");
|
||||
let dst = Path::new(&out_dir).join("test.rs");
|
||||
|
||||
let mut registry = syntex::Registry::new();
|
||||
|
||||
serde_codegen::register(&mut registry);
|
||||
registry.expand("", &src, &dst).unwrap();
|
||||
serde_codegen::expand(&src, &dst).unwrap();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::error;
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
use std::collections::{btree_map, BTreeMap};
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
use std::iter::Peekable;
|
||||
|
||||
use Value;
|
||||
|
@ -19,7 +22,9 @@ pub struct Decoder {
|
|||
/// whether fields were decoded or not.
|
||||
pub toml: Option<Value>,
|
||||
cur_field: Option<String>,
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
cur_map: Peekable<btree_map::IntoIter<String, Value>>,
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
leftover_map: ::Table,
|
||||
}
|
||||
|
||||
|
@ -115,30 +120,39 @@ impl Decoder {
|
|||
/// This decoder can be passed to the `Decodable` methods or driven
|
||||
/// manually.
|
||||
pub fn new(toml: Value) -> Decoder {
|
||||
Decoder {
|
||||
toml: Some(toml),
|
||||
cur_field: None,
|
||||
leftover_map: BTreeMap::new(),
|
||||
cur_map: BTreeMap::new().into_iter().peekable(),
|
||||
}
|
||||
Decoder::new_empty(Some(toml), None)
|
||||
}
|
||||
|
||||
fn sub_decoder(&self, toml: Option<Value>, field: &str) -> Decoder {
|
||||
Decoder {
|
||||
toml: toml,
|
||||
cur_field: if field.is_empty() {
|
||||
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 {
|
||||
toml: toml,
|
||||
cur_field: cur_field,
|
||||
leftover_map: BTreeMap::new(),
|
||||
cur_map: BTreeMap::new().into_iter().peekable(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "rustc-serialize"))]
|
||||
fn new_empty(toml: Option<Value>, cur_field: Option<String>) -> Decoder {
|
||||
Decoder {
|
||||
toml: toml,
|
||||
cur_field: cur_field,
|
||||
}
|
||||
}
|
||||
|
||||
fn err(&self, kind: DecodeErrorKind) -> DecodeError {
|
||||
DecodeError {
|
||||
field: self.cur_field.clone(),
|
||||
|
|
|
@ -3,6 +3,43 @@ use Value;
|
|||
use super::{Decoder, DecodeError, DecodeErrorKind};
|
||||
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 {
|
||||
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)
|
||||
-> Result<V::Value, DecodeError>
|
||||
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
|
||||
{
|
||||
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)
|
||||
|
@ -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)
|
||||
-> Result<V::Value, DecodeError>
|
||||
where V: de::Visitor
|
||||
|
@ -186,6 +294,62 @@ impl de::Deserializer for Decoder {
|
|||
let mut d = <() as ValueDeserializer<Self::Error>>::into_deserializer(());
|
||||
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 {
|
||||
|
@ -270,6 +434,39 @@ impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
|
|||
{
|
||||
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>
|
||||
|
@ -492,6 +689,38 @@ impl de::Deserializer for UnitDeserializer {
|
|||
{
|
||||
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 {
|
||||
|
|
|
@ -35,7 +35,7 @@ use {Value, Table};
|
|||
/// assert_eq!(e.toml.get(&"foo".to_string()), Some(&Value::Integer(4)))
|
||||
/// # }
|
||||
/// ```
|
||||
#[derive(Default)]
|
||||
#[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.
|
||||
|
@ -66,8 +66,9 @@ pub enum Error {
|
|||
Custom(String),
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum State {
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[doc(hidden)]
|
||||
pub enum State {
|
||||
Start,
|
||||
NextKey(String),
|
||||
NextArray(Vec<Value>),
|
||||
|
@ -112,17 +113,27 @@ impl Encoder {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
fn seq<F>(&mut self, f: F) -> 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));
|
||||
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) {
|
||||
State::NextArray(v) => self.emit_value(Value::Array(v)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
fn table<F>(&mut self, f: F) -> 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>
|
||||
where F: FnOnce(&mut Encoder) -> Result<(), Error>
|
||||
{
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
use serde::ser;
|
||||
use Value;
|
||||
use super::{Encoder, Error};
|
||||
use super::{Encoder, Error, State};
|
||||
|
||||
impl ser::Serializer for Encoder {
|
||||
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> {
|
||||
self.emit_value(Value::Boolean(v))
|
||||
|
@ -14,12 +21,42 @@ impl ser::Serializer for Encoder {
|
|||
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(())
|
||||
}
|
||||
|
@ -34,33 +71,99 @@ impl ser::Serializer for Encoder {
|
|||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
fn serialize_seq<V>(&mut self, mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::SeqVisitor
|
||||
{
|
||||
self.seq(|me| {
|
||||
while try!(visitor.visit(me)).is_some() {}
|
||||
Ok(())
|
||||
})
|
||||
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));
|
||||
}
|
||||
fn serialize_seq_elt<T>(&mut self, value: T) -> Result<(), Error>
|
||||
self.serialize_seq_end(state)
|
||||
}
|
||||
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
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
fn serialize_map<V>(&mut self, mut visitor: V) -> Result<(), Error>
|
||||
where V: ser::MapVisitor
|
||||
{
|
||||
self.table(|me| {
|
||||
while try!(visitor.visit(me)).is_some() {}
|
||||
Ok(())
|
||||
})
|
||||
fn serialize_seq_end(&mut self, state: State) -> Result<(), Error> {
|
||||
self.seq_end(state)
|
||||
}
|
||||
fn serialize_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
|
||||
where K: ser::Serialize, V: ser::Serialize
|
||||
fn serialize_tuple(&mut self, len: usize) -> Result<State, Error> {
|
||||
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)));
|
||||
try!(value.serialize(self));
|
||||
Ok(())
|
||||
self.serialize_seq_elt(state, value)
|
||||
}
|
||||
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,
|
||||
_name: &'static str,
|
||||
|
@ -80,6 +183,14 @@ impl ser::Serializer for Encoder {
|
|||
// 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 {
|
||||
|
@ -93,12 +204,19 @@ impl ser::Serialize for Value {
|
|||
Value::Boolean(b) => e.serialize_bool(b),
|
||||
Value::Datetime(ref s) => e.serialize_str(s),
|
||||
Value::Array(ref a) => {
|
||||
e.serialize_seq(ser::impls::SeqIteratorVisitor::new(a.iter(),
|
||||
Some(a.len())))
|
||||
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) => {
|
||||
e.serialize_map(ser::impls::MapIteratorVisitor::new(t.iter(),
|
||||
Some(t.len())))
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue