aboutsummaryrefslogtreecommitdiff
path: root/src/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder')
-rw-r--r--src/decoder/mod.rs240
-rw-r--r--src/decoder/rustc_serialize.rs371
-rw-r--r--src/decoder/serde.rs773
3 files changed, 0 insertions, 1384 deletions
diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs
deleted file mode 100644
index 51a9ea2..0000000
--- a/src/decoder/mod.rs
+++ /dev/null
@@ -1,240 +0,0 @@
-use std::error;
-use std::fmt;
-
-use std::collections::{btree_map, BTreeMap};
-use std::iter::Peekable;
-
-use Value;
-use self::DecodeErrorKind::*;
-
-#[cfg(feature = "rustc-serialize")] mod rustc_serialize;
-#[cfg(feature = "serde")] mod serde;
-
-/// A structure to transform TOML values into Rust values.
-///
-/// This decoder implements the serialization `Decoder` interface, allowing
-/// `Decodable` types to be generated by this decoder. The input is any
-/// arbitrary TOML value.
-pub struct Decoder {
- /// The TOML value left over after decoding. This can be used to inspect
- /// whether fields were decoded or not.
- pub toml: Option<Value>,
- cur_field: Option<String>,
-
- // These aren't used if serde is in use
- #[cfg_attr(feature = "serde", allow(dead_code))]
- cur_map: Peekable<btree_map::IntoIter<String, Value>>,
- #[cfg_attr(feature = "serde", allow(dead_code))]
- leftover_map: ::Table,
-}
-
-/// Description for errors which can occur while decoding a type.
-#[derive(PartialEq, Debug)]
-pub struct DecodeError {
- /// Field that this error applies to.
- pub field: Option<String>,
- /// The type of error which occurred while decoding,
- pub kind: DecodeErrorKind,
-}
-
-/// Enumeration of possible errors which can occur while decoding a structure.
-#[derive(PartialEq, Debug)]
-pub enum DecodeErrorKind {
- /// An error flagged by the application, e.g. value out of range
- ApplicationError(String),
- /// A field was expected, but none was found.
- ExpectedField(/* type */ Option<&'static str>),
- /// A field was found, but it was not an expected one.
- UnknownField,
- /// A field was found, but it had the wrong type.
- ExpectedType(/* expected */ &'static str, /* found */ &'static str),
- /// The nth map key was expected, but none was found.
- ExpectedMapKey(usize),
- /// The nth map element was expected, but none was found.
- ExpectedMapElement(usize),
- /// An enum decoding was requested, but no variants were supplied
- NoEnumVariants,
- /// The unit type was being decoded, but a non-zero length string was found
- NilTooLong,
- /// There was an error with the syntactical structure of the TOML.
- SyntaxError,
- /// A custom error was generated when decoding.
- CustomError(String),
- /// The end of the TOML input was reached too soon
- EndOfStream,
- /// Produced by serde ...
- InvalidType(&'static str),
-}
-
-/// Decodes a TOML value into a decodable type.
-///
-/// This function will consume the given TOML value and attempt to decode it
-/// into the type specified. If decoding fails, `None` will be returned. If a
-/// finer-grained error is desired, then it is recommended to use `Decodable`
-/// directly.
-#[cfg(feature = "rustc-serialize")]
-pub fn decode<T: ::rustc_serialize::Decodable>(toml: Value) -> Option<T> {
- ::rustc_serialize::Decodable::decode(&mut Decoder::new(toml)).ok()
-}
-
-/// Decodes a TOML value into a decodable type.
-///
-/// This function will consume the given TOML value and attempt to decode it
-/// into the type specified. If decoding fails, `None` will be returned. If a
-/// finer-grained error is desired, then it is recommended to use `Decodable`
-/// directly.
-#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
-pub fn decode<T: ::serde::Deserialize>(toml: Value) -> Option<T> {
- ::serde::Deserialize::deserialize(&mut Decoder::new(toml)).ok()
-}
-
-/// Decodes a string into a toml-encoded value.
-///
-/// This function will parse the given string into a TOML value, and then parse
-/// the TOML value into the desired type. If any error occurs, `None` is
-/// returned.
-///
-/// If more fine-grained errors are desired, these steps should be driven
-/// manually.
-#[cfg(feature = "rustc-serialize")]
-pub fn decode_str<T: ::rustc_serialize::Decodable>(s: &str) -> Option<T> {
- ::Parser::new(s).parse().and_then(|t| decode(Value::Table(t)))
-}
-
-/// Decodes a string into a toml-encoded value.
-///
-/// This function will parse the given string into a TOML value, and then parse
-/// the TOML value into the desired type. If any error occurs, `None` is
-/// returned.
-///
-/// If more fine-grained errors are desired, these steps should be driven
-/// manually.
-#[cfg(all(not(feature = "rustc-serialize"), feature = "serde"))]
-pub fn decode_str<T: ::serde::Deserialize>(s: &str) -> Option<T> {
- ::Parser::new(s).parse().and_then(|t| decode(Value::Table(t)))
-}
-
-impl Decoder {
- /// Creates a new decoder, consuming the TOML value to decode.
- ///
- /// This decoder can be passed to the `Decodable` methods or driven
- /// manually.
- 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)
- }
-
- 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(),
- }
- }
-
- fn err(&self, kind: DecodeErrorKind) -> DecodeError {
- DecodeError {
- field: self.cur_field.clone(),
- kind: kind,
- }
- }
-
- fn mismatch(&self, expected: &'static str,
- found: &Option<Value>) -> DecodeError{
- match *found {
- Some(ref val) => self.err(ExpectedType(expected, val.type_str())),
- None => self.err(ExpectedField(Some(expected))),
- }
- }
-}
-
-impl fmt::Display for DecodeError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- try!(match self.kind {
- ApplicationError(ref err) => {
- write!(f, "{}", err)
- }
- ExpectedField(expected_type) => {
- match expected_type {
- Some("table") => write!(f, "expected a section"),
- Some(e) => write!(f, "expected a value of type `{}`", e),
- None => write!(f, "expected a value"),
- }
- }
- UnknownField => write!(f, "unknown field"),
- ExpectedType(expected, found) => {
- fn humanize(s: &str) -> String {
- if s == "section" {
- "a section".to_string()
- } else {
- format!("a value of type `{}`", s)
- }
- }
- write!(f, "expected {}, but found {}",
- humanize(expected),
- humanize(found))
- }
- ExpectedMapKey(idx) => {
- write!(f, "expected at least {} keys", idx + 1)
- }
- ExpectedMapElement(idx) => {
- write!(f, "expected at least {} elements", idx + 1)
- }
- NoEnumVariants => {
- write!(f, "expected an enum variant to decode to")
- }
- NilTooLong => {
- write!(f, "expected 0-length string")
- }
- SyntaxError => {
- write!(f, "syntax error")
- }
- EndOfStream => {
- write!(f, "end of stream")
- }
- InvalidType(s) => {
- write!(f, "invalid type: {}", s)
- }
- CustomError(ref s) => {
- write!(f, "custom error: {}", s)
- }
- });
- match self.field {
- Some(ref s) => {
- write!(f, " for the key `{}`", s)
- }
- None => Ok(())
- }
- }
-}
-
-impl error::Error for DecodeError {
- fn description(&self) -> &str {
- match self.kind {
- ApplicationError(ref s) => &**s,
- ExpectedField(..) => "expected a field",
- UnknownField => "found an unknown field",
- ExpectedType(..) => "expected a type",
- ExpectedMapKey(..) => "expected a map key",
- ExpectedMapElement(..) => "expected a map element",
- NoEnumVariants => "no enum variants to decode to",
- NilTooLong => "nonzero length string representing nil",
- SyntaxError => "syntax error",
- EndOfStream => "end of stream",
- InvalidType(..) => "invalid type",
- CustomError(..) => "custom error",
- }
- }
-}
diff --git a/src/decoder/rustc_serialize.rs b/src/decoder/rustc_serialize.rs
deleted file mode 100644
index f850663..0000000
--- a/src/decoder/rustc_serialize.rs
+++ /dev/null
@@ -1,371 +0,0 @@
-use rustc_serialize;
-use std::mem;
-use std::collections::BTreeMap;
-
-use super::{Decoder, DecodeError};
-use super::DecodeErrorKind::*;
-use Value;
-
-impl rustc_serialize::Decoder for Decoder {
- type Error = DecodeError;
- fn read_nil(&mut self) -> Result<(), DecodeError> {
- match self.toml {
- Some(Value::String(ref s)) if s.is_empty() => {}
- Some(Value::String(..)) => return Err(self.err(NilTooLong)),
- ref found => return Err(self.mismatch("string", found)),
- }
- self.toml.take();
- Ok(())
- }
- fn read_usize(&mut self) -> Result<usize, DecodeError> {
- self.read_i64().map(|i| i as usize)
- }
- fn read_u64(&mut self) -> Result<u64, DecodeError> {
- self.read_i64().map(|i| i as u64)
- }
- fn read_u32(&mut self) -> Result<u32, DecodeError> {
- self.read_i64().map(|i| i as u32)
- }
- fn read_u16(&mut self) -> Result<u16, DecodeError> {
- self.read_i64().map(|i| i as u16)
- }
- fn read_u8(&mut self) -> Result<u8, DecodeError> {
- self.read_i64().map(|i| i as u8)
- }
- fn read_isize(&mut self) -> Result<isize, DecodeError> {
- self.read_i64().map(|i| i as isize)
- }
- fn read_i64(&mut self) -> Result<i64, DecodeError> {
- match self.toml {
- Some(Value::Integer(i)) => { self.toml.take(); Ok(i) }
- ref found => Err(self.mismatch("integer", found)),
- }
- }
- fn read_i32(&mut self) -> Result<i32, DecodeError> {
- self.read_i64().map(|i| i as i32)
- }
- fn read_i16(&mut self) -> Result<i16, DecodeError> {
- self.read_i64().map(|i| i as i16)
- }
- fn read_i8(&mut self) -> Result<i8, DecodeError> {
- self.read_i64().map(|i| i as i8)
- }
- fn read_bool(&mut self) -> Result<bool, DecodeError> {
- match self.toml {
- Some(Value::Boolean(b)) => { self.toml.take(); Ok(b) }
- ref found => Err(self.mismatch("bool", found)),
- }
- }
- fn read_f64(&mut self) -> Result<f64, DecodeError> {
- match self.toml {
- Some(Value::Float(f)) => { self.toml.take(); Ok(f) },
- ref found => Err(self.mismatch("float", found)),
- }
- }
- fn read_f32(&mut self) -> Result<f32, DecodeError> {
- self.read_f64().map(|f| f as f32)
- }
- fn read_char(&mut self) -> Result<char, DecodeError> {
- let ch = match self.toml {
- Some(Value::String(ref s)) if s.chars().count() == 1 =>
- s.chars().next().unwrap(),
- ref found => return Err(self.mismatch("string", found)),
- };
- self.toml.take();
- Ok(ch)
- }
- fn read_str(&mut self) -> Result<String, DecodeError> {
- match self.toml.take() {
- Some(Value::String(s)) => Ok(s),
- found => {
- let err = Err(self.mismatch("string", &found));
- self.toml = found;
- err
- }
- }
- }
-
- // Compound types:
- fn read_enum<T, F>(&mut self, _name: &str, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- f(self)
- }
-
- fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F)
- -> Result<T, DecodeError>
- where F: FnMut(&mut Decoder, usize) -> Result<T, DecodeError>
- {
- // When decoding enums, this crate takes the strategy of trying to
- // decode the current TOML as all of the possible variants, returning
- // success on the first one that succeeds.
- //
- // Note that fidelity of the errors returned here is a little nebulous,
- // but we try to return the error that had the relevant field as the
- // longest field. This way we hopefully match an error against what was
- // most likely being written down without losing too much info.
- let mut first_error = None::<DecodeError>;
- for i in 0..names.len() {
- let mut d = self.sub_decoder(self.toml.clone(), "");
- match f(&mut d, i) {
- Ok(t) => {
- self.toml = d.toml;
- return Ok(t)
- }
- Err(e) => {
- if let Some(ref first) = first_error {
- let my_len = e.field.as_ref().map(|s| s.len());
- let first_len = first.field.as_ref().map(|s| s.len());
- if my_len <= first_len {
- continue
- }
- }
- first_error = Some(e);
- }
- }
- }
- Err(first_error.unwrap_or_else(|| self.err(NoEnumVariants)))
- }
- fn read_enum_variant_arg<T, F>(&mut self, _a_idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- f(self)
- }
-
- fn read_enum_struct_variant<T, F>(&mut self, _names: &[&str], _f: F)
- -> Result<T, DecodeError>
- where F: FnMut(&mut Decoder, usize) -> Result<T, DecodeError>
- {
- panic!()
- }
- fn read_enum_struct_variant_field<T, F>(&mut self,
- _f_name: &str,
- _f_idx: usize,
- _f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- panic!()
- }
-
- fn read_struct<T, F>(&mut self, _s_name: &str, _len: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- match self.toml {
- Some(Value::Table(..)) => {
- let ret = try!(f(self));
- match self.toml {
- Some(Value::Table(ref t)) if t.is_empty() => {}
- _ => return Ok(ret)
- }
- self.toml.take();
- Ok(ret)
- }
- ref found => Err(self.mismatch("table", found)),
- }
- }
- fn read_struct_field<T, F>(&mut self, f_name: &str, _f_idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- let field = f_name.to_string();
- let toml = match self.toml {
- Some(Value::Table(ref mut table)) => {
- table.remove(&field)
- .or_else(|| table.remove(&f_name.replace("_", "-")))
- },
- ref found => return Err(self.mismatch("table", found)),
- };
- let mut d = self.sub_decoder(toml, f_name);
- let ret = try!(f(&mut d));
- if let Some(value) = d.toml {
- if let Some(Value::Table(ref mut table)) = self.toml {
- table.insert(field, value);
- }
- }
- Ok(ret)
- }
-
- fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- self.read_seq(move |d, len| {
- assert!(len == tuple_len,
- "expected tuple of length `{}`, found tuple \
- of length `{}`", tuple_len, len);
- f(d)
- })
- }
- fn read_tuple_arg<T, F>(&mut self, a_idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- self.read_seq_elt(a_idx, f)
- }
-
- fn read_tuple_struct<T, F>(&mut self, _s_name: &str, _len: usize, _f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- panic!()
- }
- fn read_tuple_struct_arg<T, F>(&mut self, _a_idx: usize, _f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- panic!()
- }
-
- // Specialized types:
- fn read_option<T, F>(&mut self, mut f: F)
- -> Result<T, DecodeError>
- where F: FnMut(&mut Decoder, bool) -> Result<T, DecodeError>
- {
- match self.toml {
- Some(..) => f(self, true),
- None => f(self, false),
- }
- }
-
- fn read_seq<T, F>(&mut self, f: F) -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder, usize) -> Result<T, DecodeError>
- {
- let len = match self.toml {
- Some(Value::Array(ref arr)) => arr.len(),
- None => 0,
- ref found => return Err(self.mismatch("array", found)),
- };
- let ret = try!(f(self, len));
- match self.toml {
- Some(Value::Array(ref mut arr)) => {
- arr.retain(|slot| slot.as_integer() != Some(0));
- if !arr.is_empty() { return Ok(ret) }
- }
- _ => return Ok(ret)
- }
- self.toml.take();
- Ok(ret)
- }
- fn read_seq_elt<T, F>(&mut self, idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- let toml = match self.toml {
- Some(Value::Array(ref mut arr)) => {
- mem::replace(&mut arr[idx], Value::Integer(0))
- }
- ref found => return Err(self.mismatch("array", found)),
- };
- let mut d = self.sub_decoder(Some(toml), "");
- let ret = try!(f(&mut d));
- if let Some(toml) = d.toml {
- if let Some(Value::Array(ref mut arr)) = self.toml {
- arr[idx] = toml;
- }
- }
- Ok(ret)
- }
-
- fn read_map<T, F>(&mut self, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder, usize) -> Result<T, DecodeError>
- {
- let map = match self.toml.take() {
- Some(Value::Table(table)) => table,
- found => {
- self.toml = found;
- return Err(self.mismatch("table", &self.toml))
- }
- };
- let amt = map.len();
- let prev_iter = mem::replace(&mut self.cur_map,
- map.into_iter().peekable());
- let prev_map = mem::replace(&mut self.leftover_map, BTreeMap::new());
- let ret = try!(f(self, amt));
- let leftover = mem::replace(&mut self.leftover_map, prev_map);
- self.cur_map = prev_iter;
- if !leftover.is_empty() {
- self.toml = Some(Value::Table(leftover));
- }
- Ok(ret)
- }
- fn read_map_elt_key<T, F>(&mut self, idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- let key = match self.cur_map.peek().map(|p| p.0.clone()) {
- Some(k) => k,
- None => return Err(self.err(ExpectedMapKey(idx))),
- };
- let val = Value::String(key.clone());
- f(&mut self.sub_decoder(Some(val), &key))
- }
- fn read_map_elt_val<T, F>(&mut self, idx: usize, f: F)
- -> Result<T, DecodeError>
- where F: FnOnce(&mut Decoder) -> Result<T, DecodeError>
- {
- match self.cur_map.next() {
- Some((key, value)) => {
- let mut d = self.sub_decoder(Some(value), &key);
- let ret = f(&mut d);
- if let Some(toml) = d.toml.take() {
- self.leftover_map.insert(key, toml);
- }
- ret
- }
- None => Err(self.err(ExpectedMapElement(idx))),
- }
- }
-
- fn error(&mut self, err: &str) -> DecodeError {
- DecodeError {
- field: self.cur_field.clone(),
- kind: ApplicationError(err.to_string())
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use rustc_serialize::Decodable;
- use std::collections::HashMap;
-
- use {Parser, Decoder, Value};
-
- #[test]
- fn bad_enum_chooses_longest_error() {
- #[derive(RustcDecodable)]
- #[allow(dead_code)]
- struct Foo {
- wut: HashMap<String, Bar>,
- }
-
- #[derive(RustcDecodable)]
- enum Bar {
- Simple(String),
- Detailed(Baz),
- }
-
- #[derive(RustcDecodable, Debug)]
- struct Baz {
- features: Vec<String>,
- }
-
- let s = r#"
- [wut]
- a = { features = "" }
- "#;
- let v = Parser::new(s).parse().unwrap();
- let mut d = Decoder::new(Value::Table(v));
- let err = match Foo::decode(&mut d) {
- Ok(_) => panic!("expected error"),
- Err(e) => e,
- };
- assert_eq!(err.field.as_ref().unwrap(), "wut.a.features");
-
- }
-}
diff --git a/src/decoder/serde.rs b/src/decoder/serde.rs
deleted file mode 100644
index 81a2bae..0000000
--- a/src/decoder/serde.rs
+++ /dev/null
@@ -1,773 +0,0 @@
-use serde::de;
-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;
-
- fn deserialize<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor
- {
- match self.toml.take() {
- Some(Value::String(s)) => visitor.visit_string(s),
- Some(Value::Integer(i)) => visitor.visit_i64(i),
- Some(Value::Float(f)) => visitor.visit_f64(f),
- Some(Value::Boolean(b)) => visitor.visit_bool(b),
- Some(Value::Datetime(s)) => visitor.visit_string(s),
- Some(Value::Array(a)) => {
- let len = a.len();
- let iter = a.into_iter();
- visitor.visit_seq(SeqDeserializer::new(iter, len, &mut self.toml))
- }
- Some(Value::Table(t)) => {
- visitor.visit_map(MapVisitor {
- iter: t.into_iter(),
- de: self,
- key: None,
- value: None,
- })
- }
- None => Err(self.err(DecodeErrorKind::EndOfStream)),
- }
- }
-
- fn deserialize_bool<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor
- {
- match self.toml.take() {
- Some(Value::Boolean(b)) => visitor.visit_bool(b),
- ref found => Err(self.mismatch("bool", found)),
- }
- }
-
- 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
- {
- match self.toml.take() {
- Some(Value::Integer(f)) => visitor.visit_i64(f),
- ref found => Err(self.mismatch("integer", found)),
- }
- }
-
- fn deserialize_isize<V>(&mut self, visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor
- {
- 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)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor
- {
- match self.toml.take() {
- Some(Value::Float(f)) => visitor.visit_f64(f),
- ref found => Err(self.mismatch("float", found)),
- }
- }
-
- fn deserialize_str<V>(&mut self, mut visitor: V)
- -> Result<V::Value, Self::Error>
- where V: de::Visitor,
- {
- match self.toml.take() {
- Some(Value::String(s)) => visitor.visit_string(s),
- ref found => Err(self.mismatch("string", found)),
- }
- }
-
- 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
- {
- match self.toml.take() {
- Some(Value::String(ref s)) if s.chars().count() == 1 => {
- visitor.visit_char(s.chars().next().unwrap())
- }
- ref found => return Err(self.mismatch("string", found)),
- }
- }
-
- fn deserialize_option<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor
- {
- if self.toml.is_none() {
- visitor.visit_none()
- } else {
- visitor.visit_some(self)
- }
- }
-
- fn deserialize_seq<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- if self.toml.is_none() {
- let iter = None::<i32>.into_iter();
- visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0))
- } else {
- self.deserialize(visitor)
- }
- }
-
- fn deserialize_map<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- match self.toml.take() {
- Some(Value::Table(t)) => {
- visitor.visit_map(MapVisitor {
- iter: t.into_iter(),
- de: self,
- key: None,
- value: None,
- })
- }
- ref found => Err(self.mismatch("table", found)),
- }
- }
-
- fn deserialize_enum<V>(&mut self,
- _enum: &str,
- variants: &[&str],
- mut visitor: V) -> Result<V::Value, DecodeError>
- where V: de::EnumVisitor,
- {
- // When decoding enums, this crate takes the strategy of trying to
- // decode the current TOML as all of the possible variants, returning
- // success on the first one that succeeds.
- //
- // Note that fidelity of the errors returned here is a little nebulous,
- // but we try to return the error that had the relevant field as the
- // longest field. This way we hopefully match an error against what was
- // most likely being written down without losing too much info.
- let mut first_error = None::<DecodeError>;
-
- for variant in 0..variants.len() {
- let mut de = VariantVisitor {
- de: self.sub_decoder(self.toml.clone(), ""),
- variant: variant,
- };
-
- match visitor.visit(&mut de) {
- Ok(value) => {
- self.toml = de.de.toml;
- return Ok(value);
- }
- Err(e) => {
- if let Some(ref first) = first_error {
- let my_len = e.field.as_ref().map(|s| s.len());
- let first_len = first.field.as_ref().map(|s| s.len());
- if my_len <= first_len {
- continue
- }
- }
- first_error = Some(e);
- }
- }
- }
-
- Err(first_error.unwrap_or_else(|| self.err(DecodeErrorKind::NoEnumVariants)))
- }
-
- // When #[derive(Deserialize)] encounters an unknown struct field it will
- // call this method (somehow), and we want to preserve all unknown struct
- // fields to return them upwards (to warn about unused keys), so we override
- // that here to not tamper with our own internal state.
- fn deserialize_ignored_any<V>(&mut self, visitor: V)
- -> Result<V::Value, Self::Error>
- where V: de::Visitor
- {
- use serde::de::value::ValueDeserializer;
- 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 {
- de: Decoder,
- variant: usize,
-}
-
-impl de::VariantVisitor for VariantVisitor {
- type Error = DecodeError;
-
- fn visit_variant<V>(&mut self) -> Result<V, DecodeError>
- where V: de::Deserialize
- {
- use serde::de::value::ValueDeserializer;
-
- let mut de = self.variant.into_deserializer();
-
- de::Deserialize::deserialize(&mut de)
- }
-
- fn visit_unit(&mut self) -> Result<(), DecodeError> {
- de::Deserialize::deserialize(&mut self.de)
- }
-
- fn visit_newtype<T>(&mut self) -> Result<T, DecodeError>
- where T: de::Deserialize,
- {
- de::Deserialize::deserialize(&mut self.de)
- }
-
- fn visit_tuple<V>(&mut self,
- _len: usize,
- visitor: V) -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- de::Deserializer::deserialize(&mut self.de, visitor)
- }
-
- fn visit_struct<V>(&mut self,
- _fields: &'static [&'static str],
- visitor: V) -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- de::Deserializer::deserialize(&mut self.de, visitor)
- }
-}
-
-struct SeqDeserializer<'a, I> {
- iter: I,
- len: usize,
- toml: &'a mut Option<Value>,
-}
-
-impl<'a, I> SeqDeserializer<'a, I> where I: Iterator<Item=Value> {
- fn new(iter: I, len: usize, toml: &'a mut Option<Value>) -> Self {
- SeqDeserializer {
- iter: iter,
- len: len,
- toml: toml,
- }
- }
-
- fn put_value_back(&mut self, v: Value) {
- *self.toml = self.toml.take().or(Some(Value::Array(Vec::new())));
- match self.toml.as_mut().unwrap() {
- &mut Value::Array(ref mut a) => {
- a.push(v);
- },
- _ => unreachable!(),
- }
- }
-}
-
-impl<'a, I> de::Deserializer for SeqDeserializer<'a, I>
- where I: Iterator<Item=Value>,
-{
- type Error = DecodeError;
-
- fn deserialize<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- 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>
- where I: Iterator<Item=Value>
-{
- type Error = DecodeError;
-
- fn visit<V>(&mut self) -> Result<Option<V>, DecodeError>
- where V: de::Deserialize
- {
- match self.iter.next() {
- Some(value) => {
- self.len -= 1;
- let mut de = Decoder::new(value);
- let v = try!(de::Deserialize::deserialize(&mut de));
- if let Some(t) = de.toml {
- self.put_value_back(t);
- }
- Ok(Some(v))
- }
- None => Ok(None),
- }
- }
-
- fn end(&mut self) -> Result<(), DecodeError> {
- if self.len == 0 {
- Ok(())
- } else {
- Err(de::Error::end_of_stream())
- }
- }
-
- fn size_hint(&self) -> (usize, Option<usize>) {
- (self.len, Some(self.len))
- }
-}
-
-impl de::Error for DecodeError {
- fn custom<T: Into<String>>(msg: T) -> DecodeError {
- DecodeError {
- field: None,
- kind: DecodeErrorKind::CustomError(msg.into()),
- }
- }
- fn end_of_stream() -> DecodeError {
- DecodeError { field: None, kind: DecodeErrorKind::EndOfStream }
- }
- fn missing_field(name: &'static str) -> DecodeError {
- DecodeError {
- field: Some(name.to_string()),
- kind: DecodeErrorKind::ExpectedField(None),
- }
- }
- fn unknown_field(name: &str) -> DecodeError {
- DecodeError {
- field: Some(name.to_string()),
- kind: DecodeErrorKind::UnknownField,
- }
- }
- fn invalid_type(ty: de::Type) -> Self {
- DecodeError {
- field: None,
- kind: DecodeErrorKind::InvalidType(match ty {
- de::Type::Bool => "bool",
- de::Type::Usize |
- de::Type::U8 |
- de::Type::U16 |
- de::Type::U32 |
- de::Type::U64 |
- de::Type::Isize |
- de::Type::I8 |
- de::Type::I16 |
- de::Type::I32 |
- de::Type::I64 => "integer",
- de::Type::F32 |
- de::Type::F64 => "float",
- de::Type::Char |
- de::Type::Str |
- de::Type::String => "string",
- de::Type::Seq => "array",
- de::Type::Struct |
- de::Type::Map => "table",
- de::Type::Unit => "Unit",
- de::Type::Option => "Option",
- de::Type::UnitStruct => "UnitStruct",
- de::Type::NewtypeStruct => "NewtypeStruct",
- de::Type::TupleStruct => "TupleStruct",
- de::Type::FieldName => "FieldName",
- de::Type::Tuple => "Tuple",
- de::Type::Enum => "Enum",
- de::Type::VariantName => "VariantName",
- de::Type::StructVariant => "StructVariant",
- de::Type::TupleVariant => "TupleVariant",
- de::Type::UnitVariant => "UnitVariant",
- de::Type::Bytes => "Bytes",
- })
- }
- }
-}
-
-struct MapVisitor<'a, I> {
- iter: I,
- de: &'a mut Decoder,
- key: Option<String>,
- value: Option<Value>,
-}
-
-impl<'a, I> MapVisitor<'a, I> {
- fn put_value_back(&mut self, v: Value) {
- self.de.toml = self.de.toml.take().or_else(|| {
- Some(Value::Table(BTreeMap::new()))
- });
-
- match self.de.toml.as_mut().unwrap() {
- &mut Value::Table(ref mut t) => {
- t.insert(self.key.take().unwrap(), v);
- },
- _ => unreachable!(),
- }
- }
-}
-
-impl<'a, I> de::MapVisitor for MapVisitor<'a, I>
- where I: Iterator<Item=(String, Value)>
-{
- type Error = DecodeError;
-
- fn visit_key<K>(&mut self) -> Result<Option<K>, DecodeError>
- where K: de::Deserialize
- {
- while let Some((k, v)) = self.iter.next() {
- let mut dec = self.de.sub_decoder(Some(Value::String(k.clone())), &k);
- self.key = Some(k);
-
- match de::Deserialize::deserialize(&mut dec) {
- Ok(val) => {
- self.value = Some(v);
- return Ok(Some(val))
- }
-
- // If this was an unknown field, then we put the toml value
- // back into the map and keep going.
- Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => {
- self.put_value_back(v);
- }
-
- Err(e) => return Err(e),
- }
- }
- Ok(None)
- }
-
- fn visit_value<V>(&mut self) -> Result<V, DecodeError>
- where V: de::Deserialize
- {
- match self.value.take() {
- Some(t) => {
- let mut dec = {
- // Borrowing the key here because Rust doesn't have
- // non-lexical borrows yet.
- let key = match self.key {
- Some(ref key) => &**key,
- None => ""
- };
-
- self.de.sub_decoder(Some(t), key)
- };
- let v = try!(de::Deserialize::deserialize(&mut dec));
- if let Some(t) = dec.toml {
- self.put_value_back(t);
- }
- Ok(v)
- },
- None => Err(de::Error::end_of_stream())
- }
- }
-
- fn end(&mut self) -> Result<(), DecodeError> {
- if let Some(v) = self.value.take() {
- self.put_value_back(v);
- }
- while let Some((k, v)) = self.iter.next() {
- self.key = Some(k);
- self.put_value_back(v);
- }
- Ok(())
- }
-
- fn missing_field<V>(&mut self, field_name: &'static str)
- -> Result<V, DecodeError> where V: de::Deserialize {
- // See if the type can deserialize from a unit.
- match de::Deserialize::deserialize(&mut UnitDeserializer) {
- Err(DecodeError {
- kind: DecodeErrorKind::InvalidType(..),
- field,
- }) => Err(DecodeError {
- field: field.or(Some(field_name.to_string())),
- kind: DecodeErrorKind::ExpectedField(None),
- }),
- v => v,
- }
- }
-}
-
-struct UnitDeserializer;
-
-impl de::Deserializer for UnitDeserializer {
- type Error = DecodeError;
-
- fn deserialize<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- visitor.visit_unit()
- }
-
- fn deserialize_option<V>(&mut self, mut visitor: V)
- -> Result<V::Value, DecodeError>
- where V: de::Visitor,
- {
- 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 {
- fn deserialize<D>(deserializer: &mut D) -> Result<Value, D::Error>
- where D: de::Deserializer
- {
- struct ValueVisitor;
-
- impl de::Visitor for ValueVisitor {
- type Value = Value;
-
- fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
- Ok(Value::Boolean(value))
- }
-
- fn visit_i64<E>(&mut self, value: i64) -> Result<Value, E> {
- Ok(Value::Integer(value))
- }
-
- fn visit_f64<E>(&mut self, value: f64) -> Result<Value, E> {
- Ok(Value::Float(value))
- }
-
- fn visit_str<E>(&mut self, value: &str) -> Result<Value, E> {
- Ok(Value::String(value.into()))
- }
-
- fn visit_string<E>(&mut self, value: String) -> Result<Value, E> {
- Ok(Value::String(value))
- }
-
- fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
- where V: de::SeqVisitor
- {
- let values = try!(de::impls::VecVisitor::new().visit_seq(visitor));
- Ok(Value::Array(values))
- }
-
- fn visit_map<V>(&mut self, visitor: V) -> Result<Value, V::Error>
- where V: de::MapVisitor
- {
- let mut v = de::impls::BTreeMapVisitor::new();
- let values = try!(v.visit_map(visitor));
- Ok(Value::Table(values))
- }
- }
-
- deserializer.deserialize(ValueVisitor)
- }
-}