From d02e62233088df15fd43b86aa97e0695b375a46b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 7 Mar 2016 23:48:01 -0800 Subject: [PATCH] WIP --- Cargo.toml | 2 +- serde-tests/Cargo.lock | 75 +++++++++-------------------- serde-tests/Cargo.toml | 6 +-- serde-tests/test.rs.in | 2 +- src/decoder/mod.rs | 6 +++ src/decoder/serde.rs | 106 +++++++++++++++++++++++++---------------- src/encoder/mod.rs | 3 ++ src/encoder/serde.rs | 62 +++++++++++++----------- 8 files changed, 134 insertions(+), 128 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0b146ac..fc0249f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ facilitate deserializing and serializing Rust structures. [dependencies] rustc-serialize = { optional = true, version = "0.3.0" } -serde = { optional = true, version = "0.6" } +serde = { optional = true, version = "0.7" } [features] default = ["rustc-serialize"] diff --git a/serde-tests/Cargo.lock b/serde-tests/Cargo.lock index b5adca3..0077453 100644 --- a/serde-tests/Cargo.lock +++ b/serde-tests/Cargo.lock @@ -2,27 +2,18 @@ name = "serde-tests" version = "0.1.0" dependencies = [ - "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.1.27", ] -[[package]] -name = "advapi32-sys" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.5 (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 = "aster" -version = "0.9.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -52,41 +43,22 @@ dependencies = [ "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "quasi" -version = "0.3.10" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "quasi_codegen" -version = "0.3.10" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -96,35 +68,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "serde_codegen" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aster 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", - "quasi_codegen 0.3.10 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", - "syntex_syntax 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "aster 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quasi_codegen 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syntex" -version = "0.22.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "syntex_syntax 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex_syntax 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "syntex_syntax" -version = "0.23.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -149,7 +118,7 @@ name = "toml" version = "0.1.27" dependencies = [ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/serde-tests/Cargo.toml b/serde-tests/Cargo.toml index 85d477e..31e85f1 100644 --- a/serde-tests/Cargo.toml +++ b/serde-tests/Cargo.toml @@ -5,12 +5,12 @@ authors = ["Alex Crichton "] build = "build.rs" [dependencies] -serde = "0.6" +serde = "0.7" toml = { path = "..", features = ["serde"] } [build-dependencies] -syntex = "0.22" -serde_codegen = "0.6" +syntex = "0.29" +serde_codegen = "0.7" [lib] name = "serde_tests" diff --git a/serde-tests/test.rs.in b/serde-tests/test.rs.in index 41ec27a..15bb164 100644 --- a/serde-tests/test.rs.in +++ b/serde-tests/test.rs.in @@ -82,7 +82,7 @@ fn application_decode_error() { fn deserialize(d: &mut D) -> Result { let x: usize = try!(Deserialize::deserialize(d)); if x > 10 { - Err(serde::de::Error::syntax("more than 10")) + Err(serde::de::Error::custom("more than 10")) } else { Ok(Range10(x)) } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 7c444e0..6180c13 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -53,6 +53,8 @@ pub enum DecodeErrorKind { 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, } @@ -195,6 +197,9 @@ impl fmt::Display for DecodeError { EndOfStream => { write!(f, "end of stream") } + CustomError(ref s) => { + write!(f, "custom error: {}", s) + } }); match self.field { Some(ref s) => { @@ -218,6 +223,7 @@ impl error::Error for DecodeError { NilTooLong => "nonzero length string representing nil", SyntaxError => "syntax error", EndOfStream => "end of stream", + CustomError(..) => "custom error", } } } diff --git a/src/decoder/serde.rs b/src/decoder/serde.rs index 47221b6..493b8fd 100644 --- a/src/decoder/serde.rs +++ b/src/decoder/serde.rs @@ -5,27 +5,32 @@ use std::collections::BTreeMap; fn se2toml(err: de::value::Error, ty: &'static str) -> DecodeError { match err { - de::value::Error::SyntaxError => de::Error::syntax(ty), - de::value::Error::EndOfStreamError => de::Error::end_of_stream(), - de::value::Error::MissingFieldError(s) => { + de::value::Error::Custom(s) => de::Error::custom(s), + de::value::Error::EndOfStream => de::Error::end_of_stream(), + de::value::Error::MissingField(s) => { DecodeError { field: Some(s.to_string()), kind: DecodeErrorKind::ExpectedField(Some(ty)), } }, - de::value::Error::UnknownFieldError(s) => { + de::value::Error::UnknownField(s) => { DecodeError { field: Some(s.to_string()), kind: DecodeErrorKind::UnknownField, } }, + de::value::Error::InvalidType(ty) => de::Error::invalid_type(ty), + de::value::Error::InvalidLength(l) => de::Error::invalid_length(l), + de::value::Error::InvalidValue(v) => de::Error::invalid_value(&v), + de::value::Error::UnknownVariant(v) => de::Error::unknown_variant(&v), } } impl de::Deserializer for Decoder { type Error = DecodeError; - fn visit(&mut self, mut visitor: V) -> Result + fn deserialize(&mut self, mut visitor: V) + -> Result where V: de::Visitor { match self.toml.take() { @@ -61,30 +66,34 @@ impl de::Deserializer for Decoder { } } - fn visit_isize(&mut self, visitor: V) -> Result + fn deserialize_isize(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_i8(&mut self, visitor: V) -> Result + fn deserialize_i8(&mut self, visitor: V) -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_i16(&mut self, visitor: V) -> Result + fn deserialize_i16(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_i32(&mut self, visitor: V) -> Result + fn deserialize_i32(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_i64(&mut self, mut visitor: V) -> Result + fn deserialize_i64(&mut self, mut visitor: V) + -> Result where V: de::Visitor { match self.toml.take() { @@ -95,42 +104,47 @@ impl de::Deserializer for Decoder { } } - fn visit_usize(&mut self, visitor: V) -> Result + fn deserialize_usize(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_u8(&mut self, visitor: V) -> Result + fn deserialize_u8(&mut self, visitor: V) -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_u16(&mut self, visitor: V) -> Result + fn deserialize_u16(&mut self, visitor: V) -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_u32(&mut self, visitor: V) -> Result + fn deserialize_u32(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_u64(&mut self, visitor: V) -> Result + fn deserialize_u64(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_i64(visitor) + self.deserialize_i64(visitor) } - fn visit_f32(&mut self, visitor: V) -> Result + fn deserialize_f32(&mut self, visitor: V) + -> Result where V: de::Visitor { - self.visit_f64(visitor) + self.deserialize_f64(visitor) } - fn visit_f64(&mut self, mut visitor: V) -> Result + fn deserialize_f64(&mut self, mut visitor: V) + -> Result where V: de::Visitor { match self.toml.take() { @@ -141,7 +155,8 @@ impl de::Deserializer for Decoder { } } - fn visit_option(&mut self, mut visitor: V) -> Result + fn deserialize_option(&mut self, mut visitor: V) + -> Result where V: de::Visitor { if self.toml.is_none() { @@ -151,7 +166,8 @@ impl de::Deserializer for Decoder { } } - fn visit_seq(&mut self, mut visitor: V) -> Result + fn deserialize_seq(&mut self, mut visitor: V) + -> Result where V: de::Visitor, { if self.toml.is_none() { @@ -159,14 +175,14 @@ impl de::Deserializer for Decoder { let e = visitor.visit_seq(de::value::SeqDeserializer::new(iter, 0)); e.map_err(|e| se2toml(e, "array")) } else { - self.visit(visitor) + self.deserialize(visitor) } } - fn visit_enum(&mut self, - _enum: &str, - variants: &[&str], - mut visitor: V) -> Result + fn deserialize_enum(&mut self, + _enum: &str, + variants: &[&str], + mut visitor: V) -> Result where V: de::EnumVisitor, { // When decoding enums, this crate takes the strategy of trying to @@ -240,7 +256,7 @@ impl de::VariantVisitor for VariantVisitor { visitor: V) -> Result where V: de::Visitor, { - de::Deserializer::visit(&mut self.de, visitor) + de::Deserializer::deserialize(&mut self.de, visitor) } fn visit_struct(&mut self, @@ -248,7 +264,7 @@ impl de::VariantVisitor for VariantVisitor { visitor: V) -> Result where V: de::Visitor, { - de::Deserializer::visit(&mut self.de, visitor) + de::Deserializer::deserialize(&mut self.de, visitor) } } @@ -283,7 +299,8 @@ impl<'a, I> de::Deserializer for SeqDeserializer<'a, I> { type Error = DecodeError; - fn visit(&mut self, mut visitor: V) -> Result + fn deserialize(&mut self, mut visitor: V) + -> Result where V: de::Visitor, { visitor.visit_seq(self) @@ -326,8 +343,11 @@ impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I> } impl de::Error for DecodeError { - fn syntax(_: &str) -> DecodeError { - DecodeError { field: None, kind: DecodeErrorKind::SyntaxError } + fn custom>(msg: T) -> DecodeError { + DecodeError { + field: None, + kind: DecodeErrorKind::CustomError(msg.into()), + } } fn end_of_stream() -> DecodeError { DecodeError { field: None, kind: DecodeErrorKind::EndOfStream } @@ -448,13 +468,15 @@ struct UnitDeserializer; impl de::Deserializer for UnitDeserializer { type Error = DecodeError; - fn visit(&mut self, mut visitor: V) -> Result + fn deserialize(&mut self, mut visitor: V) + -> Result where V: de::Visitor, { visitor.visit_unit() } - fn visit_option(&mut self, mut visitor: V) -> Result + fn deserialize_option(&mut self, mut visitor: V) + -> Result where V: de::Visitor, { visitor.visit_none() @@ -506,6 +528,6 @@ impl de::Deserialize for Value { } } - deserializer.visit(ValueVisitor) + deserializer.deserialize(ValueVisitor) } } diff --git a/src/encoder/mod.rs b/src/encoder/mod.rs index cdfe8e2..fb628fa 100644 --- a/src/encoder/mod.rs +++ b/src/encoder/mod.rs @@ -61,6 +61,8 @@ pub enum Error { /// Indicates that a type other than a string was attempted to be used as a /// map key type. InvalidMapKeyType, + /// A custom error type was generated + Custom(String), } #[derive(PartialEq)] @@ -202,6 +204,7 @@ impl fmt::Display for Error { at this location"), Error::InvalidMapKeyType => write!(f, "only strings can be used as \ key types"), + Error::Custom(ref s) => write!(f, "custom error: {}", s), } } } diff --git a/src/encoder/serde.rs b/src/encoder/serde.rs index 3b50181..d5bbb77 100644 --- a/src/encoder/serde.rs +++ b/src/encoder/serde.rs @@ -5,33 +5,33 @@ use super::{Encoder, Error}; impl ser::Serializer for Encoder { type Error = Error; - fn visit_bool(&mut self, v: bool) -> Result<(), Error> { + fn serialize_bool(&mut self, v: bool) -> Result<(), Error> { self.emit_value(Value::Boolean(v)) } - fn visit_i64(&mut self, v: i64) -> Result<(), Error> { + fn serialize_i64(&mut self, v: i64) -> Result<(), Error> { self.emit_value(Value::Integer(v)) } - fn visit_u64(&mut self, v: u64) -> Result<(), Error> { - self.visit_i64(v as i64) + fn serialize_u64(&mut self, v: u64) -> Result<(), Error> { + self.serialize_i64(v as i64) } - fn visit_f64(&mut self, v: f64) -> Result<(), Error> { + fn serialize_f64(&mut self, v: f64) -> Result<(), Error> { self.emit_value(Value::Float(v)) } - fn visit_str(&mut self, value: &str) -> Result<(), Error> { + fn serialize_str(&mut self, value: &str) -> Result<(), Error> { self.emit_value(Value::String(value.to_string())) } - fn visit_unit(&mut self) -> Result<(), Error> { + fn serialize_unit(&mut self) -> Result<(), Error> { Ok(()) } - fn visit_none(&mut self) -> Result<(), Error> { + fn serialize_none(&mut self) -> Result<(), Error> { self.emit_none() } - fn visit_some(&mut self, value: V) -> Result<(), Error> + fn serialize_some(&mut self, value: V) -> Result<(), Error> where V: ser::Serialize { value.serialize(self) } - fn visit_seq(&mut self, mut visitor: V) -> Result<(), Error> + fn serialize_seq(&mut self, mut visitor: V) -> Result<(), Error> where V: ser::SeqVisitor { self.seq(|me| { @@ -39,12 +39,12 @@ impl ser::Serializer for Encoder { Ok(()) }) } - fn visit_seq_elt(&mut self, value: T) -> Result<(), Error> + fn serialize_seq_elt(&mut self, value: T) -> Result<(), Error> where T: ser::Serialize { value.serialize(self) } - fn visit_map(&mut self, mut visitor: V) -> Result<(), Error> + fn serialize_map(&mut self, mut visitor: V) -> Result<(), Error> where V: ser::MapVisitor { self.table(|me| { @@ -52,26 +52,26 @@ impl ser::Serializer for Encoder { Ok(()) }) } - fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Error> + fn serialize_map_elt(&mut self, key: K, value: V) -> Result<(), Error> where K: ser::Serialize, V: ser::Serialize { try!(self.table_key(|me| key.serialize(me))); try!(value.serialize(self)); Ok(()) } - fn visit_newtype_struct(&mut self, - _name: &'static str, - value: T) -> Result<(), Self::Error> + fn serialize_newtype_struct(&mut self, + _name: &'static str, + value: T) -> Result<(), Self::Error> where T: ser::Serialize, { // Don't serialize the newtype struct in a tuple. value.serialize(self) } - fn visit_newtype_variant(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static str, - value: T) -> Result<(), Self::Error> + fn serialize_newtype_variant(&mut self, + _name: &'static str, + _variant_index: usize, + _variant: &'static str, + value: T) -> Result<(), Self::Error> where T: ser::Serialize, { // Don't serialize the newtype struct variant in a tuple. @@ -84,19 +84,25 @@ impl ser::Serialize for Value { where E: ser::Serializer { match *self { - Value::String(ref s) => e.visit_str(s), - Value::Integer(i) => e.visit_i64(i), - Value::Float(f) => e.visit_f64(f), - Value::Boolean(b) => e.visit_bool(b), - Value::Datetime(ref s) => e.visit_str(s), + Value::String(ref s) => e.serialize_str(s), + Value::Integer(i) => e.serialize_i64(i), + Value::Float(f) => e.serialize_f64(f), + Value::Boolean(b) => e.serialize_bool(b), + Value::Datetime(ref s) => e.serialize_str(s), Value::Array(ref a) => { - e.visit_seq(ser::impls::SeqIteratorVisitor::new(a.iter(), + e.serialize_seq(ser::impls::SeqIteratorVisitor::new(a.iter(), Some(a.len()))) } Value::Table(ref t) => { - e.visit_map(ser::impls::MapIteratorVisitor::new(t.iter(), + e.serialize_map(ser::impls::MapIteratorVisitor::new(t.iter(), Some(t.len()))) } } } } + +impl ser::Error for Error { + fn custom>(msg: T) -> Error { + Error::Custom(msg.into()) + } +}