Compare commits

...

52 Commits

Author SHA1 Message Date
David Tolnay 5d9c1aeb06 Release 0.9.0 2017-01-25 12:57:45 -08:00
David Tolnay 59e48997dd Release 0.9.0-rc4 2017-01-25 10:14:43 -08:00
Oliver Schneider ffcd97834f Merge pull request #721 from serde-rs/size
Remove usize and isize from data model
2017-01-25 19:08:02 +01:00
David Tolnay e0c049dbf2 Remove usize and isize from data model 2017-01-25 09:08:06 -08:00
David Tolnay 8cb6607e82 Merge pull request #719 from serde-rs/rustdoc
Serde rustdoc
2017-01-24 20:59:26 -08:00
David Tolnay 1ffb0570b6 Do not require rustdoc tests to run on stable 2017-01-24 20:47:31 -08:00
David Tolnay 2c1dd60575 Serde rustdoc 2017-01-24 20:37:11 -08:00
David Tolnay 24f849da2d Remove unused #[macro_use]
I think this was for the quasi-quoting macros back in the day.
2017-01-24 09:28:00 -08:00
David Tolnay a5024a4238 Merge pull request #717 from serde-rs/badger
add travis badge to crates.io
2017-01-24 05:35:55 -08:00
Oliver Schneider b105423e5e add travis badge to crates.io 2017-01-24 10:30:10 +01:00
Oliver Schneider 42c1bc2907 Merge pull request #716 from serde-rs/ref
Serialize T by ref
2017-01-24 08:31:24 +01:00
David Tolnay c334c1c7b5 Release 0.9.0-rc3 2017-01-23 19:14:02 -08:00
David Tolnay 92668d7061 Serialize T by ref 2017-01-23 17:11:18 -08:00
David Tolnay b9d865d8e7 Merge pull request #715 from serde-rs/nostd
Support serde_derive on no_std
2017-01-23 16:13:25 -08:00
David Tolnay fc4e370ba9 Support serde_derive on no_std 2017-01-23 16:03:06 -08:00
Oliver Schneider a982d27536 Merge pull request #700 from serde-rs/usize
Restore visit_usize and visit_bytes for identifying variants
2017-01-23 11:27:06 +01:00
Oliver Schneider dc87826298 Merge pull request #699 from serde-rs/fields
Remove visit_usize from Duration impl
2017-01-23 11:26:18 +01:00
David Tolnay a09a8a039a All combinations of features compile without warnings 2017-01-23 01:45:54 -08:00
David Tolnay ea702755a2 Merge branch master into origin/usize
Conflicts:
    serde_codegen/src/de.rs
    testing/tests/test_de.rs
2017-01-23 01:36:49 -08:00
David Tolnay d161911c63 Merge branch master into origin/fields
Conflicts:
    serde/src/de/impls.rs
2017-01-23 01:28:01 -08:00
Oliver Schneider e27553d3df Merge pull request #710 from serde-rs/errors
Errors redesign
2017-01-23 10:25:48 +01:00
David Tolnay 48eaf988bc Add free-form option for Unexpected 2017-01-22 05:02:24 -08:00
David Tolnay 73a364d4fd Capture byte value for error message 2017-01-22 04:57:12 -08:00
David Tolnay 6dfdcb6ba1 Merge pull request #713 from serde-rs/zero
Suppress warning about using num::Zero
2017-01-21 19:20:57 -08:00
David Tolnay 089c7eb1d7 Suppress warning about using num::Zero 2017-01-21 19:14:56 -08:00
David Tolnay 1e05fc2145 Release 0.9.0-rc2 2017-01-21 16:30:13 -08:00
David Tolnay 977612d8dd Merge branch origin/missing into origin/errors 2017-01-21 16:28:24 -08:00
David Tolnay 5855078703 Fix backward invalid_length messages in value deserializer 2017-01-21 14:38:33 -08:00
David Tolnay 3c88a93fb2 Fix the filtered error messages 2017-01-21 12:34:04 -08:00
David Tolnay 530c29466e Merge pull request #711 from serde-rs/names
Filter the slice of expected field and variant names
2017-01-21 12:25:43 -08:00
David Tolnay ea99e8b686 Filter the slice of expected field and variant names 2017-01-21 12:18:55 -08:00
David Tolnay 2a148112d4 Fix Box<str> use on no_std 2017-01-21 10:17:48 -08:00
David Tolnay a4126e4c5a Errors 2017-01-21 09:13:01 -08:00
David Tolnay d1325862f7 Merge tag v0.8.23 into master
Conflicts:
    serde/Cargo.toml
    serde_codegen/Cargo.toml
    serde_derive/Cargo.toml
    serde_test/Cargo.toml
    testing/Cargo.toml
2017-01-20 15:29:32 -08:00
David Tolnay 1f65ce75ec Release 0.8.23 2017-01-20 15:25:57 -08:00
Jake Goulding 9536e52aa6 Add categories to Cargo.toml 2017-01-20 15:09:11 -08:00
Oliver Schneider be0c755731 Merge pull request #705 from serde-rs/inlineseed
Inline <PhantomData<T> as DeserializeSeed>::deserialize
2017-01-20 14:34:24 +01:00
David Tolnay 42bc63bed8 Standardize behavior of missing fields 2017-01-20 00:44:43 -08:00
David Tolnay e41b940a3d Inline <PhantomData<T> as DeserializeSeed>::deserialize 2017-01-19 16:17:27 -08:00
David Tolnay 88149fc0c3 Fix key and value seed variable names
Rename fail.
2017-01-19 13:44:18 -08:00
David Tolnay 5ecfb3b388 Update serde_test to use seeds 2017-01-19 01:24:33 -08:00
David Tolnay 13a9f929de Stateful deserialization 2017-01-19 01:17:59 -08:00
David Tolnay e40fbe0767 Restore visit_bytes for Duration impl 2017-01-18 21:13:51 -08:00
David Tolnay 0a10116bf5 Restore visit_bytes for identifying variants and fields 2017-01-18 21:11:51 -08:00
David Tolnay b1fbbfd3ce Restore visit_usize for identifying variants 2017-01-17 23:52:06 -08:00
David Tolnay 984ebcead0 Remove visit_usize and visit_bytes for Duration impl 2017-01-17 23:32:28 -08:00
David Tolnay aa88f01cdc Merge pull request #697 from serde-rs/vanity
cleanup some deprecation warnings
2017-01-17 09:26:44 -08:00
David Tolnay 13794c1b48 Stop testing on rust 1.12.0 2017-01-17 09:19:39 -08:00
Oliver Schneider b5e64abba1 cleanup some deprecation warnings 2017-01-17 14:29:33 +01:00
David Tolnay 503ce310f5 Merge pull request #692 from serde-rs/byte_buf
add missing `Vec<u8>` deserialization hint to `Deserializer`
2017-01-16 08:10:25 -08:00
Oliver Schneider b26f291d93 add missing Vec<u8> deserialization hint to Deserializer 2017-01-16 16:55:13 +01:00
David Tolnay bc6bc9e3f0 Remove LICENSE file in favor of LICENSE-MIT and LICENSE-APACHE
This repo no longer contains bench_log referenced in this file.
2017-01-15 10:16:57 -08:00
32 changed files with 2781 additions and 1325 deletions
+2 -2
View File
@@ -1,7 +1,6 @@
sudo: false
language: rust
rust:
- 1.12.0
- 1.13.0
- stable
- beta
@@ -11,7 +10,7 @@ before_script:
- export PATH=$HOME/.local/bin:$PATH
script:
- (cd serde && travis-cargo build)
- (cd serde && travis-cargo --skip nightly test)
- (cd serde && travis-cargo --only beta test)
- (cd serde && travis-cargo --only nightly test -- --features unstable-testing)
- (cd serde && travis-cargo build -- --no-default-features)
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
@@ -19,6 +18,7 @@ script:
- (cd testing && travis-cargo --skip nightly test)
- (cd testing && travis-cargo --only nightly test -- --features unstable-testing)
- (cd serde_derive && travis-cargo --only nightly test)
- (cd serde_derive/no-std-tests && travis-cargo --only nightly build)
#- (cd examples/serde-syntex-example && travis-cargo --skip nightly run)
#- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --no-default-features --features unstable)
- (cd serde && travis-cargo --only stable doc)
-33
View File
@@ -1,33 +0,0 @@
See LICENSE-APACHE and LICENSE-MIT.
----
bench_log is derived from https://github.com/cloudflare/goser, which has the
following license:
Copyright (c) 2013, CloudFlare, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+8 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "0.9.0-rc1"
version = "0.9.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -9,8 +9,12 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/"
readme = "../README.md"
keywords = ["serde", "serialization"]
categories = ["encoding"]
include = ["Cargo.toml", "src/**/*.rs"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
[features]
default = ["std"]
@@ -22,3 +26,6 @@ unstable-testing = ["clippy", "unstable", "std"]
[dependencies]
clippy = { version = "^0.*", optional = true }
[dev-dependencies]
serde_derive = "0.9.0-rc4"
+65 -5
View File
@@ -1,4 +1,20 @@
//! Helper module to enable serializing bytes more efficiently
//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
//!
//! Without specialization, Rust forces us to treat `&[u8]` just like any other
//! slice and `Vec<u8>` just like any other vector. In reality this particular
//! slice and vector can often be serialized and deserialized in a more
//! efficient, compact representation in many formats.
//!
//! When working with such a format, you can opt into specialized handling of
//! `&[u8]` by wrapping it in `bytes::Bytes` and `Vec<u8>` by wrapping it in
//! `bytes::ByteBuf`.
//!
//! Rust support for specialization is being tracked in
//! [rust-lang/rust#31844][specialization]. Once it lands in the stable compiler
//! we will be deprecating these wrapper types in favor of optimizing `&[u8]`
//! and `Vec<u8>` out of the box.
//!
//! [specialization]: https://github.com/rust-lang/rust/issues/31844
use core::{ops, fmt, char, iter, slice};
use core::fmt::Write;
@@ -6,14 +22,36 @@ use core::fmt::Write;
use ser;
#[cfg(any(feature = "std", feature = "collections"))]
pub use self::bytebuf::{ByteBuf, ByteBufVisitor};
pub use self::bytebuf::ByteBuf;
#[cfg(any(feature = "std", feature = "collections"))]
#[doc(hidden)] // does anybody need this?
pub use self::bytebuf::ByteBufVisitor;
#[cfg(feature = "collections")]
use collections::Vec;
///////////////////////////////////////////////////////////////////////////////
/// `Bytes` wraps a `&[u8]` in order to serialize into a byte array.
/// Wraps a `&[u8]` in order to serialize in an efficient way. Does not support
/// deserialization.
///
/// ```rust
/// # #[macro_use] extern crate serde_derive;
/// # extern crate serde;
/// # use std::net::IpAddr;
/// #
/// use serde::bytes::Bytes;
///
/// # #[allow(dead_code)]
/// #[derive(Serialize)]
/// struct Packet<'a> {
/// destination: IpAddr,
/// payload: Bytes<'a>,
/// }
/// #
/// # fn main() {}
/// ```
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct Bytes<'a> {
bytes: &'a [u8],
@@ -86,7 +124,25 @@ mod bytebuf {
#[cfg(feature = "collections")]
use collections::{String, Vec};
/// `ByteBuf` wraps a `Vec<u8>` and serializes as a byte array.
/// Wraps a `Vec<u8>` in order to serialize and deserialize in an efficient
/// way.
///
/// ```rust
/// # #[macro_use] extern crate serde_derive;
/// # extern crate serde;
/// # use std::net::IpAddr;
/// #
/// use serde::bytes::ByteBuf;
///
/// # #[allow(dead_code)]
/// #[derive(Serialize, Deserialize)]
/// struct Packet {
/// destination: IpAddr,
/// payload: ByteBuf,
/// }
/// #
/// # fn main() {}
/// ```
#[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ByteBuf {
bytes: Vec<u8>,
@@ -181,6 +237,10 @@ mod bytebuf {
impl de::Visitor for ByteBufVisitor {
type Value = ByteBuf;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("byte array")
}
#[inline]
fn visit_unit<E>(self) -> Result<ByteBuf, E>
where E: de::Error,
@@ -234,7 +294,7 @@ mod bytebuf {
fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
where D: de::Deserializer
{
deserializer.deserialize_bytes(ByteBufVisitor)
deserializer.deserialize_byte_buf(ByteBufVisitor)
}
}
}
+140 -108
View File
@@ -2,7 +2,7 @@
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "unstable", feature = "collections", not(feature = "std")))]
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
@@ -27,11 +27,13 @@ use std::collections::{
VecDeque,
};
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
use collections::enum_set::{CLike, EnumSet};
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
use collections::borrow::ToOwned;
use core::fmt;
#[cfg(feature = "std")]
use core::hash::{Hash, BuildHasher};
use core::marker::PhantomData;
#[cfg(feature = "std")]
@@ -42,15 +44,15 @@ use core::str;
#[cfg(feature = "std")]
use std::rc::Rc;
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::rc::Rc;
#[cfg(feature = "std")]
use std::sync::Arc;
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::arc::Arc;
#[cfg(all(feature = "unstable", feature = "alloc", not(feature = "std")))]
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
#[cfg(feature = "std")]
@@ -60,6 +62,7 @@ use std::time::Duration;
use core::nonzero::{NonZero, Zeroable};
#[cfg(feature = "unstable")]
#[allow(deprecated)] // required for impl Deserialize for NonZero<T>
use core::num::Zero;
use de::{
@@ -69,7 +72,7 @@ use de::{
Error,
MapVisitor,
SeqVisitor,
Type,
Unexpected,
VariantVisitor,
Visitor,
};
@@ -83,6 +86,10 @@ pub struct UnitVisitor;
impl Visitor for UnitVisitor {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("unit")
}
fn visit_unit<E>(self) -> Result<(), E>
where E: Error,
{
@@ -112,6 +119,10 @@ pub struct BoolVisitor;
impl Visitor for BoolVisitor {
type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a boolean")
}
fn visit_bool<E>(self, v: bool) -> Result<bool, E>
where E: Error,
{
@@ -124,7 +135,7 @@ impl Visitor for BoolVisitor {
match s.trim_matches(::utils::Pattern_White_Space) {
"true" => Ok(true),
"false" => Ok(false),
_ => Err(Error::invalid_type(Type::Bool)),
_ => Err(Error::invalid_type(Unexpected::Str(s), &self)),
}
}
}
@@ -140,81 +151,68 @@ impl Deserialize for bool {
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method {
($src_ty:ty, $method:ident, $from_method:ident, $ty:expr) => {
($ty:ident, $src_ty:ident, $method:ident, $from_method:ident, $group:ident, $group_ty:ident) => {
#[inline]
fn $method<E>(self, v: $src_ty) -> Result<T, E>
fn $method<E>(self, v: $src_ty) -> Result<$ty, E>
where E: Error,
{
match FromPrimitive::$from_method(v) {
Some(v) => Ok(v),
None => Err(Error::invalid_type($ty)),
None => Err(Error::invalid_value(Unexpected::$group(v as $group_ty), &self)),
}
}
}
}
/// A visitor that produces a primitive type.
struct PrimitiveVisitor<T> {
marker: PhantomData<T>,
}
impl<T> PrimitiveVisitor<T> {
/// Construct a new `PrimitiveVisitor`.
#[inline]
fn new() -> Self {
PrimitiveVisitor {
marker: PhantomData,
}
}
}
impl<T> Visitor for PrimitiveVisitor<T>
where T: Deserialize + FromPrimitive + str::FromStr
{
type Value = T;
impl_deserialize_num_method!(isize, visit_isize, from_isize, Type::Isize);
impl_deserialize_num_method!(i8, visit_i8, from_i8, Type::I8);
impl_deserialize_num_method!(i16, visit_i16, from_i16, Type::I16);
impl_deserialize_num_method!(i32, visit_i32, from_i32, Type::I32);
impl_deserialize_num_method!(i64, visit_i64, from_i64, Type::I64);
impl_deserialize_num_method!(usize, visit_usize, from_usize, Type::Usize);
impl_deserialize_num_method!(u8, visit_u8, from_u8, Type::U8);
impl_deserialize_num_method!(u16, visit_u16, from_u16, Type::U16);
impl_deserialize_num_method!(u32, visit_u32, from_u32, Type::U32);
impl_deserialize_num_method!(u64, visit_u64, from_u64, Type::U64);
impl_deserialize_num_method!(f32, visit_f32, from_f32, Type::F32);
impl_deserialize_num_method!(f64, visit_f64, from_f64, Type::F64);
#[inline]
fn visit_str<E>(self, s: &str) -> Result<T, E>
where E: Error,
{
str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| {
Err(Error::invalid_type(Type::Str))
})
}
}
macro_rules! impl_deserialize_num {
($ty:ty, $method:ident) => {
($ty:ident, $method:ident) => {
impl Deserialize for $ty {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
where D: Deserializer,
{
deserializer.$method(PrimitiveVisitor::new())
struct PrimitiveVisitor;
impl Visitor for PrimitiveVisitor {
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(stringify!($ty))
}
impl_deserialize_num_method!($ty, i8, visit_i8, from_i8, Signed, i64);
impl_deserialize_num_method!($ty, i16, visit_i16, from_i16, Signed, i64);
impl_deserialize_num_method!($ty, i32, visit_i32, from_i32, Signed, i64);
impl_deserialize_num_method!($ty, i64, visit_i64, from_i64, Signed, i64);
impl_deserialize_num_method!($ty, u8, visit_u8, from_u8, Unsigned, u64);
impl_deserialize_num_method!($ty, u16, visit_u16, from_u16, Unsigned, u64);
impl_deserialize_num_method!($ty, u32, visit_u32, from_u32, Unsigned, u64);
impl_deserialize_num_method!($ty, u64, visit_u64, from_u64, Unsigned, u64);
impl_deserialize_num_method!($ty, f32, visit_f32, from_f32, Float, f64);
impl_deserialize_num_method!($ty, f64, visit_f64, from_f64, Float, f64);
#[inline]
fn visit_str<E>(self, s: &str) -> Result<$ty, E>
where E: Error,
{
str::FromStr::from_str(s.trim_matches(::utils::Pattern_White_Space)).or_else(|_| {
Err(Error::invalid_type(Unexpected::Str(s), &self))
})
}
}
deserializer.$method(PrimitiveVisitor)
}
}
}
}
impl_deserialize_num!(isize, deserialize_isize);
impl_deserialize_num!(isize, deserialize_i64);
impl_deserialize_num!(i8, deserialize_i8);
impl_deserialize_num!(i16, deserialize_i16);
impl_deserialize_num!(i32, deserialize_i32);
impl_deserialize_num!(i64, deserialize_i64);
impl_deserialize_num!(usize, deserialize_usize);
impl_deserialize_num!(usize, deserialize_u64);
impl_deserialize_num!(u8, deserialize_u8);
impl_deserialize_num!(u16, deserialize_u16);
impl_deserialize_num!(u32, deserialize_u32);
@@ -229,6 +227,10 @@ struct CharVisitor;
impl Visitor for CharVisitor {
type Value = char;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a character")
}
#[inline]
fn visit_char<E>(self, v: char) -> Result<char, E>
where E: Error,
@@ -241,14 +243,9 @@ impl Visitor for CharVisitor {
where E: Error,
{
let mut iter = v.chars();
if let Some(v) = iter.next() {
if iter.next().is_some() {
Err(Error::invalid_type(Type::Char))
} else {
Ok(v)
}
} else {
Err(Error::end_of_stream())
match (iter.next(), iter.next()) {
(Some(c), None) => Ok(c),
_ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
}
}
}
@@ -271,6 +268,10 @@ struct StringVisitor;
impl Visitor for StringVisitor {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E>(self, v: &str) -> Result<String, E>
where E: Error,
{
@@ -294,7 +295,7 @@ impl Visitor for StringVisitor {
{
match str::from_utf8(v) {
Ok(s) => Ok(s.to_owned()),
Err(_) => Err(Error::invalid_type(Type::String)),
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
}
}
@@ -303,7 +304,7 @@ impl Visitor for StringVisitor {
{
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(_) => Err(Error::invalid_type(Type::String)),
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self)),
}
}
}
@@ -328,6 +329,10 @@ impl<
> Visitor for OptionVisitor<T> {
type Value = Option<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("option")
}
#[inline]
fn visit_unit<E>(self) -> Result<Option<T>, E>
where E: Error,
@@ -368,6 +373,10 @@ pub struct PhantomDataVisitor<T> {
impl<T> Visitor for PhantomDataVisitor<T> {
type Value = PhantomData<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("unit")
}
#[inline]
fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
where E: Error,
@@ -417,6 +426,10 @@ macro_rules! seq_impl {
{
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_unit<E>(self) -> Result<$ty, E>
where E: Error,
@@ -468,7 +481,7 @@ seq_impl!(
BTreeSet::new(),
BTreeSet::insert);
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
seq_impl!(
EnumSet<T>,
EnumSetVisitor<T: Deserialize + CLike>,
@@ -531,6 +544,10 @@ impl<A> ArrayVisitor<A> {
impl<T> Visitor for ArrayVisitor<[T; 0]> where T: Deserialize {
type Value = [T; 0];
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an empty array")
}
#[inline]
fn visit_unit<E>(self) -> Result<[T; 0], E>
where E: Error,
@@ -562,6 +579,10 @@ macro_rules! array_impls {
impl<T> Visitor for ArrayVisitor<[T; $len]> where T: Deserialize {
type Value = [T; $len];
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("an array of length ", $len))
}
#[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<[T; $len], V::Error>
where V: SeqVisitor,
@@ -569,7 +590,7 @@ macro_rules! array_impls {
$(
let $name = match try!(visitor.visit()) {
Some(val) => val,
None => return Err(Error::end_of_stream()),
None => return Err(Error::invalid_length(0, &self)),
};
)+
@@ -645,6 +666,10 @@ macro_rules! tuple_impls {
impl<$($name: Deserialize),+> Visitor for $visitor<$($name,)+> {
type Value = ($($name,)+);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
fn visit_seq<V>(self, mut visitor: V) -> Result<($($name,)+), V::Error>
@@ -653,7 +678,7 @@ macro_rules! tuple_impls {
$(
let $name = match try!(visitor.visit()) {
Some(value) => value,
None => return Err(Error::end_of_stream()),
None => return Err(Error::invalid_length(0, &self)),
};
)+
@@ -723,6 +748,10 @@ macro_rules! map_impl {
{
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a map")
}
#[inline]
fn visit_unit<E>(self) -> Result<$ty, E>
where E: Error,
@@ -785,7 +814,7 @@ impl Deserialize for net::IpAddr {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -798,7 +827,7 @@ impl Deserialize for net::Ipv4Addr {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -811,7 +840,7 @@ impl Deserialize for net::Ipv6Addr {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -826,7 +855,7 @@ impl Deserialize for net::SocketAddr {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -839,7 +868,7 @@ impl Deserialize for net::SocketAddrV4 {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -852,7 +881,7 @@ impl Deserialize for net::SocketAddrV6 {
let s = try!(String::deserialize(deserializer));
match s.parse() {
Ok(s) => Ok(s),
Err(err) => Err(D::Error::invalid_value(&err.to_string())),
Err(err) => Err(D::Error::custom(err)),
}
}
}
@@ -866,6 +895,10 @@ struct PathBufVisitor;
impl Visitor for PathBufVisitor {
type Value = path::PathBuf;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("path string")
}
fn visit_str<E>(self, v: &str) -> Result<path::PathBuf, E>
where E: Error,
{
@@ -875,7 +908,7 @@ impl Visitor for PathBufVisitor {
fn visit_string<E>(self, v: String) -> Result<path::PathBuf, E>
where E: Error,
{
self.visit_str(&v)
Ok(From::from(v))
}
}
@@ -977,14 +1010,8 @@ impl Deserialize for Duration {
impl Visitor for FieldVisitor {
type Value = Field;
fn visit_usize<E>(self, value: usize) -> Result<Field, E>
where E: Error,
{
match value {
0usize => Ok(Field::Secs),
1usize => Ok(Field::Nanos),
_ => Err(Error::invalid_value("expected a field")),
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`secs` or `nanos`")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
@@ -993,7 +1020,7 @@ impl Deserialize for Duration {
match value {
"secs" => Ok(Field::Secs),
"nanos" => Ok(Field::Nanos),
_ => Err(Error::unknown_field(value)),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
@@ -1005,7 +1032,7 @@ impl Deserialize for Duration {
b"nanos" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
Err(Error::unknown_field(&value))
Err(Error::unknown_field(&value, FIELDS))
}
}
}
@@ -1020,19 +1047,23 @@ impl Deserialize for Duration {
impl Visitor for DurationVisitor {
type Value = Duration;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Duration")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Duration, V::Error>
where V: SeqVisitor,
{
let secs: u64 = match try!(visitor.visit()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0));
return Err(Error::invalid_length(0, &self));
}
};
let nanos: u32 = match try!(visitor.visit()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1));
return Err(Error::invalid_length(1, &self));
}
};
Ok(Duration::new(secs, nanos))
@@ -1061,11 +1092,11 @@ impl Deserialize for Duration {
}
let secs = match secs {
Some(secs) => secs,
None => try!(visitor.missing_field("secs")),
None => return Err(<V::Error as Error>::missing_field("secs")),
};
let nanos = match nanos {
Some(nanos) => nanos,
None => try!(visitor.missing_field("nanos")),
None => return Err(<V::Error as Error>::missing_field("nanos")),
};
Ok(Duration::new(secs, nanos))
}
@@ -1079,11 +1110,12 @@ impl Deserialize for Duration {
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "unstable")]
#[allow(deprecated)] // num::Zero is deprecated but there is no replacement
impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable + Zero {
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error> where D: Deserializer {
let value = try!(Deserialize::deserialize(deserializer));
if value == Zero::zero() {
return Err(Error::invalid_value("expected a non-zero value"))
return Err(Error::custom("expected a non-zero value"))
}
unsafe {
Ok(NonZero::new(value))
@@ -1112,23 +1144,15 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
impl Visitor for FieldVisitor {
type Value = Field;
#[cfg(any(feature = "std", feature = "collections"))]
fn visit_usize<E>(self, value: usize) -> Result<Field, E> where E: Error {
#[cfg(feature = "collections")]
use collections::string::ToString;
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Error::unknown_field(&value.to_string())),
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`Ok` or `Err`")
}
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn visit_usize<E>(self, value: usize) -> Result<Field, E> where E: Error {
fn visit_u32<E>(self, value: u32) -> Result<Field, E> where E: Error {
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Error::unknown_field("some number")),
_ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self)),
}
}
@@ -1136,7 +1160,7 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
match value {
"Ok" => Ok(Field::Ok),
"Err" => Ok(Field::Err),
_ => Err(Error::unknown_field(value)),
_ => Err(Error::unknown_variant(value, VARIANTS)),
}
}
@@ -1146,8 +1170,8 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
b"Err" => Ok(Field::Err),
_ => {
match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_field(value)),
Err(_) => Err(Error::invalid_type(Type::String)),
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
}
}
}
@@ -1166,6 +1190,10 @@ impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
{
type Value = Result<T, E>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("enum Result")
}
fn visit_enum<V>(self, visitor: V) -> Result<Result<T, E>, V::Error>
where V: EnumVisitor
{
@@ -1198,6 +1226,10 @@ impl Deserialize for IgnoredAny {
impl Visitor for IgnoredAnyVisitor {
type Value = IgnoredAny;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("anything at all")
}
#[inline]
fn visit_bool<E>(self, _: bool) -> Result<IgnoredAny, E> {
Ok(IgnoredAny)
+1175 -366
View File
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
use core::marker::PhantomData;
use de::{Deserialize, Deserializer, Error, Visitor};
/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<V, E>(field: &'static str) -> Result<V, E>
where V: Deserialize,
E: Error
{
struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
impl<E> Deserializer for MissingFieldDeserializer<E>
where E: Error
{
type Error = E;
fn deserialize<V>(self, _visitor: V) -> Result<V::Value, E>
where V: Visitor
{
Err(Error::missing_field(self.0))
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
where V: Visitor
{
visitor.visit_none()
}
forward_to_deserialize! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
seq_fixed_size bytes byte_buf map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
let deserializer = MissingFieldDeserializer(field, PhantomData);
Deserialize::deserialize(deserializer)
}
+250 -264
View File
@@ -28,122 +28,69 @@ use collections::{
};
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::boxed::Box;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::string::ToString;
#[cfg(all(feature = "unstable", feature = "collections"))]
use collections::borrow::ToOwned;
#[cfg(feature = "std")]
use core::hash::Hash;
#[cfg(feature = "std")]
use std::error;
#[cfg(not(feature = "std"))]
use error;
use core::fmt;
use core::fmt::{self, Display};
use core::iter::{self, Iterator};
use core::marker::PhantomData;
use de::{self, SeqVisitor};
use de::{self, Expected, SeqVisitor};
use bytes;
///////////////////////////////////////////////////////////////////////////////
/// This represents all the possible errors that can occur using the `ValueDeserializer`.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
/// The value had some custom error.
#[cfg(any(feature = "std", feature = "collections"))]
Custom(String),
/// The value had some custom error.
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
Custom(&'static str),
pub struct Error(ErrorImpl);
/// The value had an incorrect type.
InvalidType(de::Type),
/// The value had an invalid length.
InvalidLength(usize),
/// The value is invalid and cannot be deserialized.
#[cfg(any(feature = "std", feature = "collections"))]
InvalidValue(String),
/// The value is invalid and cannot be deserialized.
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
InvalidValue(&'static str),
/// EOF while deserializing a value.
EndOfStream,
/// Unknown variant in enum.
#[cfg(any(feature = "std", feature = "collections"))]
UnknownVariant(String),
/// Unknown variant in enum.
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
UnknownVariant(&'static str),
/// Unknown field in struct.
#[cfg(any(feature = "std", feature = "collections"))]
UnknownField(String),
/// Unknown field in struct.
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
UnknownField(&'static str),
/// Struct is missing a field.
MissingField(&'static str),
}
#[cfg(any(feature = "std", feature = "collections"))]
type ErrorImpl = Box<str>;
#[cfg(not(any(feature = "std", feature = "collections")))]
type ErrorImpl = ();
impl de::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))]
fn custom<T: Into<String>>(msg: T) -> Self { Error::Custom(msg.into()) }
fn custom<T: Display>(msg: T) -> Self {
Error(msg.to_string().into_boxed_str())
}
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn custom<T: Into<&'static str>>(msg: T) -> Self { Error::Custom(msg.into()) }
fn end_of_stream() -> Self { Error::EndOfStream }
fn invalid_type(ty: de::Type) -> Self { Error::InvalidType(ty) }
#[cfg(any(feature = "std", feature = "collections"))]
fn invalid_value(msg: &str) -> Self { Error::InvalidValue(msg.to_owned()) }
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn invalid_value(msg: &str) -> Self { Error::InvalidValue("invalid value") }
fn invalid_length(len: usize) -> Self { Error::InvalidLength(len) }
#[cfg(any(feature = "std", feature = "collections"))]
fn unknown_variant(variant: &str) -> Self { Error::UnknownVariant(String::from(variant)) }
#[cfg(any(feature = "std", feature = "collections"))]
fn unknown_field(field: &str) -> Self { Error::UnknownField(String::from(field)) }
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn unknown_variant(variant: &str) -> Self { Error::UnknownVariant("unknown variant") }
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn unknown_field(field: &str) -> Self { Error::UnknownField("unknown field") }
fn missing_field(field: &'static str) -> Self { Error::MissingField(field) }
#[cfg(not(any(feature = "std", feature = "collections")))]
fn custom<T: Display>(_msg: T) -> Self {
Error(())
}
}
impl fmt::Display for Error {
impl Display for Error {
#[cfg(any(feature = "std", feature = "collections"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::Custom(ref s) => write!(formatter, "{}", s),
Error::EndOfStream => formatter.write_str("End of stream"),
Error::InvalidType(ty) => write!(formatter, "Invalid type, expected `{:?}`", ty),
Error::InvalidValue(ref value) => write!(formatter, "Invalid value: {}", value),
Error::InvalidLength(len) => write!(formatter, "Invalid length: {}", len),
Error::UnknownVariant(ref variant) => {
write!(formatter, "Unknown variant: {}", variant)
}
Error::UnknownField(ref field) => write!(formatter, "Unknown field: {}", field),
Error::MissingField(field) => write!(formatter, "Missing field: {}", field),
}
formatter.write_str(&self.0)
}
#[cfg(not(any(feature = "std", feature = "collections")))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str("Serde deserialization error")
}
}
impl error::Error for Error {
#[cfg(any(feature = "std", feature = "collections"))]
fn description(&self) -> &str {
"Serde Deserialization Error"
&self.0
}
fn cause(&self) -> Option<&error::Error> {
None
#[cfg(not(any(feature = "std", feature = "collections")))]
fn description(&self) -> &str {
"Serde deserialization error"
}
}
@@ -179,9 +126,9 @@ impl<E> de::Deserializer for UnitDeserializer<E>
type Error = E;
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct
struct_field tuple enum ignored_any byte_buf
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -200,7 +147,7 @@ impl<E> de::Deserializer for UnitDeserializer<E>
///////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
($ty:ty, $name:ident, $method:ident) => {
($ty:ty, $name:ident, $method:ident $($cast:tt)*) => {
/// A helper deserializer that deserializes a number.
pub struct $name<E>($ty, PhantomData<E>);
@@ -220,16 +167,15 @@ macro_rules! primitive_deserializer {
type Error = E;
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
string unit option seq seq_fixed_size bytes map unit_struct
newtype_struct tuple_struct struct struct_field tuple enum
ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit
option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any byte_buf
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
visitor.$method(self.0)
visitor.$method(self.0 $($cast)*)
}
}
}
@@ -240,12 +186,12 @@ primitive_deserializer!(i8, I8Deserializer, visit_i8);
primitive_deserializer!(i16, I16Deserializer, visit_i16);
primitive_deserializer!(i32, I32Deserializer, visit_i32);
primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_isize);
primitive_deserializer!(isize, IsizeDeserializer, visit_i64 as i64);
primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_usize);
primitive_deserializer!(usize, UsizeDeserializer, visit_u64 as u64);
primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char);
@@ -286,9 +232,9 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple ignored_any byte_buf
}
}
@@ -298,10 +244,10 @@ impl<'a, E> de::EnumVisitor for StrDeserializer<'a, E>
type Error = E;
type Variant = private::UnitOnly<E>;
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
where T: de::Deserialize,
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where T: de::DeserializeSeed,
{
de::Deserialize::deserialize(self).map(private::unit_only)
seed.deserialize(self).map(private::unit_only)
}
}
@@ -344,9 +290,9 @@ impl<E> de::Deserializer for StringDeserializer<E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple ignored_any byte_buf
}
}
@@ -357,10 +303,10 @@ impl<'a, E> de::EnumVisitor for StringDeserializer<E>
type Error = E;
type Variant = private::UnitOnly<E>;
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
where T: de::Deserialize,
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where T: de::DeserializeSeed,
{
de::Deserialize::deserialize(self).map(private::unit_only)
seed.deserialize(self).map(private::unit_only)
}
}
@@ -406,9 +352,9 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple ignored_any byte_buf
}
}
@@ -419,10 +365,10 @@ impl<'a, E> de::EnumVisitor for CowStrDeserializer<'a, E>
type Error = E;
type Variant = private::UnitOnly<E>;
fn visit_variant<T>(self) -> Result<(T, Self::Variant), Self::Error>
where T: de::Deserialize,
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where T: de::DeserializeSeed,
{
de::Deserialize::deserialize(self).map(private::unit_only)
seed.deserialize(self).map(private::unit_only)
}
}
@@ -430,22 +376,37 @@ impl<'a, E> de::EnumVisitor for CowStrDeserializer<'a, E>
/// A helper deserializer that deserializes a sequence.
pub struct SeqDeserializer<I, E> {
iter: I,
len: usize,
iter: iter::Fuse<I>,
count: usize,
marker: PhantomData<E>,
}
impl<I, E> SeqDeserializer<I, E>
where E: de::Error,
where I: Iterator,
E: de::Error,
{
/// Construct a new `SeqDeserializer<I>`.
pub fn new(iter: I, len: usize) -> Self {
pub fn new(iter: I) -> Self {
SeqDeserializer {
iter: iter,
len: len,
iter: iter.fuse(),
count: 0,
marker: PhantomData,
}
}
fn end(&mut self) -> Result<(), E> {
let mut remaining = 0;
while self.iter.next().is_some() {
remaining += 1;
}
if remaining == 0 {
Ok(())
} else {
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInSeq(self.count)))
}
}
}
impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
@@ -459,17 +420,14 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
where V: de::Visitor,
{
let v = try!(visitor.visit_seq(&mut self));
if self.len == 0 {
Ok(v)
} else {
Err(de::Error::invalid_length(self.len))
}
try!(self.end());
Ok(v)
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple enum ignored_any byte_buf
}
}
@@ -480,20 +438,32 @@ impl<I, T, E> de::SeqVisitor for SeqDeserializer<I, E>
{
type Error = E;
fn visit<V>(&mut self) -> Result<Option<V>, Self::Error>
where V: de::Deserialize
fn visit_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>, Self::Error>
where V: de::DeserializeSeed
{
match self.iter.next() {
Some(value) => {
self.len -= 1;
de::Deserialize::deserialize(value.into_deserializer()).map(Some)
self.count += 1;
seed.deserialize(value.into_deserializer()).map(Some)
}
None => Ok(None),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
self.iter.size_hint()
}
}
struct ExpectedInSeq(usize);
impl Expected for ExpectedInSeq {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.0 == 1 {
write!(formatter, "1 element in sequence")
} else {
write!(formatter, "{} elements in sequence", self.0)
}
}
}
@@ -507,8 +477,7 @@ impl<T, E> ValueDeserializer<E> for Vec<T>
type Deserializer = SeqDeserializer<vec::IntoIter<T>, E>;
fn into_deserializer(self) -> Self::Deserializer {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
SeqDeserializer::new(self.into_iter())
}
}
@@ -520,8 +489,7 @@ impl<T, E> ValueDeserializer<E> for BTreeSet<T>
type Deserializer = SeqDeserializer<btree_set::IntoIter<T>, E>;
fn into_deserializer(self) -> Self::Deserializer {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
SeqDeserializer::new(self.into_iter())
}
}
@@ -533,8 +501,7 @@ impl<T, E> ValueDeserializer<E> for HashSet<T>
type Deserializer = SeqDeserializer<hash_set::IntoIter<T>, E>;
fn into_deserializer(self) -> Self::Deserializer {
let len = self.len();
SeqDeserializer::new(self.into_iter(), len)
SeqDeserializer::new(self.into_iter())
}
}
@@ -570,75 +537,75 @@ impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple enum ignored_any byte_buf
}
}
///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a map.
pub struct MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
pub struct MapDeserializer<I, E>
where I: Iterator,
I::Item: private::Pair,
<I::Item as private::Pair>::First: ValueDeserializer<E>,
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
E: de::Error,
{
iter: I,
value: Option<V>,
len: Option<usize>,
iter: iter::Fuse<I>,
value: Option<<I::Item as private::Pair>::Second>,
count: usize,
marker: PhantomData<E>,
}
impl<I, K, V, E> MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
impl<I, E> MapDeserializer<I, E>
where I: Iterator,
I::Item: private::Pair,
<I::Item as private::Pair>::First: ValueDeserializer<E>,
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
E: de::Error,
{
/// Construct a new `MapDeserializer<I, K, V, E>` with a specific length.
pub fn new(iter: I, len: usize) -> Self {
/// Construct a new `MapDeserializer<I, K, V, E>`.
pub fn new(iter: I) -> Self {
MapDeserializer {
iter: iter,
iter: iter.fuse(),
value: None,
len: Some(len),
count: 0,
marker: PhantomData,
}
}
/// Construct a new `MapDeserializer<I, K, V, E>` that is not bounded
/// by a specific length and that delegates to `iter` for its size hint.
pub fn unbounded(iter: I) -> Self {
MapDeserializer {
iter: iter,
value: None,
len: None,
marker: PhantomData,
}
}
fn next(&mut self) -> Option<(K, V)> {
self.iter.next().map(|(k, v)| {
if let Some(len) = self.len.as_mut() {
*len -= 1;
fn next_pair(&mut self) -> Option<(<I::Item as private::Pair>::First, <I::Item as private::Pair>::Second)> {
match self.iter.next() {
Some(kv) => {
self.count += 1;
Some(private::Pair::split(kv))
}
(k, v)
})
None => None,
}
}
fn end(&mut self) -> Result<(), E> {
match self.len {
Some(len) if len > 0 => Err(de::Error::invalid_length(len)),
_ => Ok(())
let mut remaining = 0;
while self.iter.next().is_some() {
remaining += 1;
}
if remaining == 0 {
Ok(())
} else {
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(self.count + remaining, &ExpectedInMap(self.count)))
}
}
}
impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
impl<I, E> de::Deserializer for MapDeserializer<I, E>
where I: Iterator,
I::Item: private::Pair,
<I::Item as private::Pair>::First: ValueDeserializer<E>,
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
@@ -659,67 +626,58 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
Ok(value)
}
fn deserialize_seq_fixed_size<V_>(mut self, len: usize, visitor: V_) -> Result<V_::Value, Self::Error>
fn deserialize_seq_fixed_size<V_>(self, _len: usize, visitor: V_) -> Result<V_::Value, Self::Error>
where V_: de::Visitor,
{
match self.len {
Some(map_len) if map_len != len => Err(de::Error::invalid_length(len)),
_ => {
let value = try!(visitor.visit_seq(&mut self));
try!(self.end());
Ok(value)
}
}
self.deserialize_seq(visitor)
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option bytes map unit_struct newtype_struct tuple_struct struct
struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
bytes map unit_struct newtype_struct tuple_struct struct struct_field
tuple enum ignored_any byte_buf
}
}
impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
impl<I, E> de::MapVisitor for MapDeserializer<I, E>
where I: Iterator,
I::Item: private::Pair,
<I::Item as private::Pair>::First: ValueDeserializer<E>,
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed,
{
match self.next() {
match self.next_pair() {
Some((key, value)) => {
self.value = Some(value);
de::Deserialize::deserialize(key.into_deserializer()).map(Some)
seed.deserialize(key.into_deserializer()).map(Some)
}
None => Ok(None),
}
}
fn visit_value<T>(&mut self) -> Result<T, Self::Error>
where T: de::Deserialize,
fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where T: de::DeserializeSeed,
{
match self.value.take() {
Some(value) => {
de::Deserialize::deserialize(value.into_deserializer())
}
None => {
Err(de::Error::end_of_stream())
}
}
let value = self.value.take();
// Panic because this indicates a bug in the program rather than an
// expected failure.
let value = value.expect("MapVisitor::visit_value called before visit_key");
seed.deserialize(value.into_deserializer())
}
fn visit<TK, TV>(&mut self) -> Result<Option<(TK, TV)>, Self::Error>
where TK: de::Deserialize,
TV: de::Deserialize
fn visit_seed<TK, TV>(&mut self, kseed: TK, vseed: TV) -> Result<Option<(TK::Value, TV::Value)>, Self::Error>
where TK: de::DeserializeSeed,
TV: de::DeserializeSeed
{
match self.next() {
match self.next_pair() {
Some((key, value)) => {
let key = try!(de::Deserialize::deserialize(key.into_deserializer()));
let value = try!(de::Deserialize::deserialize(value.into_deserializer()));
let key = try!(kseed.deserialize(key.into_deserializer()));
let value = try!(vseed.deserialize(value.into_deserializer()));
Ok(Some((key, value)))
}
None => Ok(None)
@@ -727,34 +685,33 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.len.map_or_else(
|| self.iter.size_hint(),
|len| (len, Some(len)))
self.iter.size_hint()
}
}
impl<I, K, V, E> de::SeqVisitor for MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
impl<I, E> de::SeqVisitor for MapDeserializer<I, E>
where I: Iterator,
I::Item: private::Pair,
<I::Item as private::Pair>::First: ValueDeserializer<E>,
<I::Item as private::Pair>::Second: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed,
{
match self.next() {
match self.next_pair() {
Some((k, v)) => {
let de = PairDeserializer(k, v, PhantomData);
de::Deserialize::deserialize(de).map(Some)
seed.deserialize(de).map(Some)
}
None => Ok(None),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
de::MapVisitor::size_hint(self)
self.iter.size_hint()
}
}
@@ -770,9 +727,9 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
type Error = E;
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option bytes map unit_struct newtype_struct tuple_struct struct
struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
bytes map unit_struct newtype_struct tuple_struct struct struct_field
tuple enum ignored_any byte_buf
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -789,7 +746,10 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
if pair_visitor.1.is_none() {
Ok(pair)
} else {
Err(de::Error::invalid_length(pair_visitor.size_hint().0))
let remaining = pair_visitor.size_hint().0;
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(2, &ExpectedInSeq(2 - remaining)))
}
}
@@ -799,7 +759,9 @@ impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
if len == 2 {
self.deserialize_seq(visitor)
} else {
Err(de::Error::invalid_length(len))
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(2, &ExpectedInSeq(len)))
}
}
}
@@ -813,13 +775,13 @@ impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed,
{
if let Some(k) = self.0.take() {
de::Deserialize::deserialize(k.into_deserializer()).map(Some)
seed.deserialize(k.into_deserializer()).map(Some)
} else if let Some(v) = self.1.take() {
de::Deserialize::deserialize(v.into_deserializer()).map(Some)
seed.deserialize(v.into_deserializer()).map(Some)
} else {
Ok(None)
}
@@ -837,6 +799,18 @@ impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
}
}
struct ExpectedInMap(usize);
impl Expected for ExpectedInMap {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.0 == 1 {
write!(formatter, "1 element in map")
} else {
write!(formatter, "{} elements in map", self.0)
}
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))]
@@ -845,11 +819,10 @@ impl<K, V, E> ValueDeserializer<E> for BTreeMap<K, V>
V: ValueDeserializer<E>,
E: de::Error,
{
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, K, V, E>;
type Deserializer = MapDeserializer<btree_map::IntoIter<K, V>, E>;
fn into_deserializer(self) -> Self::Deserializer {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
MapDeserializer::new(self.into_iter())
}
}
@@ -859,11 +832,10 @@ impl<K, V, E> ValueDeserializer<E> for HashMap<K, V>
V: ValueDeserializer<E>,
E: de::Error,
{
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, K, V, E>;
type Deserializer = MapDeserializer<hash_map::IntoIter<K, V>, E>;
fn into_deserializer(self) -> Self::Deserializer {
let len = self.len();
MapDeserializer::new(self.into_iter(), len)
MapDeserializer::new(self.into_iter())
}
}
@@ -899,9 +871,9 @@ impl<V_, E> de::Deserializer for MapVisitorDeserializer<V_, E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple enum ignored_any byte_buf
}
}
@@ -932,9 +904,9 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple enum ignored_any byte_buf
}
}
@@ -968,16 +940,16 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct
struct struct_field tuple enum ignored_any byte_buf
}
}
///////////////////////////////////////////////////////////////////////////////
mod private {
use de;
use de::{self, Unexpected};
use core::marker::PhantomData;
pub struct UnitOnly<E>(PhantomData<E>);
@@ -995,26 +967,40 @@ mod private {
Ok(())
}
fn visit_newtype<T>(self) -> Result<T, Self::Error>
where T: de::Deserialize,
fn visit_newtype_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
where T: de::DeserializeSeed,
{
Err(de::Error::invalid_type(de::Type::NewtypeVariant))
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"))
}
fn visit_tuple<V>(self,
_len: usize,
_visitor: V) -> Result<V::Value, Self::Error>
_len: usize,
_visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor
{
Err(de::Error::invalid_type(de::Type::TupleVariant))
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"))
}
fn visit_struct<V>(self,
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor
{
Err(de::Error::invalid_type(de::Type::StructVariant))
Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"))
}
}
/// Avoid having to restate the generic types on `MapDeserializer`. The
/// `Iterator::Item` contains enough information to figure out K and V.
pub trait Pair {
type First;
type Second;
fn split(self) -> (Self::First, Self::Second);
}
impl<A, B> Pair for (A, B) {
type First = A;
type Second = B;
fn split(self) -> (A, B) { self }
}
}
-29
View File
@@ -1,30 +1,7 @@
//! A stand-in for `std::error`
use core::any::TypeId;
use core::fmt::{Debug, Display};
/// A stand-in for `std::error::Error`, which requires no allocation.
#[cfg(feature = "unstable")]
pub trait Error: Debug + Display + ::core::marker::Reflect {
/// A short description of the error.
///
/// The description should not contain newlines or sentence-ending
/// punctuation, to facilitate embedding in larger user-facing
/// strings.
fn description(&self) -> &str;
/// The lower-level cause of this error, if any.
fn cause(&self) -> Option<&Error> { None }
/// Get the `TypeId` of `self`
#[doc(hidden)]
fn type_id(&self) -> TypeId where Self: 'static {
TypeId::of::<Self>()
}
}
/// A stand-in for `std::error::Error`, which requires no allocation.
#[cfg(not(feature = "unstable"))]
pub trait Error: Debug + Display {
/// A short description of the error.
///
@@ -35,10 +12,4 @@ pub trait Error: Debug + Display {
/// The lower-level cause of this error, if any.
fn cause(&self) -> Option<&Error> { None }
/// Stubbed! Returns type_id of `()`
#[doc(hidden)]
fn type_id(&self) -> TypeId where Self: 'static {
TypeId::of::<()>()
}
}
+33
View File
@@ -0,0 +1,33 @@
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::String;
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
pub use core::default::Default;
pub use core::fmt;
pub use core::marker::PhantomData;
pub use core::result::Result;
#[cfg(any(feature = "collections", feature = "std"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
//
// let value = &_serde::export::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "collections", feature = "std")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
use core::str;
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
}
+74 -25
View File
@@ -1,58 +1,107 @@
//! Serde Serialization Framework
//! # Serde
//!
//! Serde is a powerful framework that enables serialization libraries to generically serialize
//! Rust data structures without the overhead of runtime type information. In many situations, the
//! handshake protocol between serializers and serializees can be completely optimized away,
//! leaving serde to perform roughly the same speed as a hand written serializer for a specific
//! type.
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! For a detailed tutorial on the different ways to use serde please check out the
//! [github repository](https://github.com/serde-rs/serde)
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website https://serde.rs/ for additional documentation and
//! usage examples.
//!
//! ### Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's code
//! generation to automatically derive implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform roughly the same speed as a handwritten serializer
//! for the specific selection of data structure and data format.
//!
//! ### Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON](https://github.com/serde-rs/json), the ubiquitous JavaScript Object
//! Notation used by many HTTP APIs.
//! - [Bincode](https://github.com/TyOverby/bincode), a compact binary format
//! used for IPC within the Servo rendering engine.
//! - [CBOR](https://github.com/pyfisch/cbor), a Concise Binary Object
//! Representation designed for small message size without the need for
//! version negotiation.
//! - [YAML](https://github.com/dtolnay/serde-yaml), a popular human-friendly
//! configuration language that ain't markup language.
//! - [MessagePack](https://github.com/3Hren/msgpack-rust), an efficient binary
//! format that resembles a compact JSON.
//! - [TOML](https://github.com/alexcrichton/toml-rs), a minimal configuration
//! format used by [Cargo](http://doc.crates.io/manifest.html).
//! - [Pickle](https://github.com/birkenfeld/serde-pickle), a format common in
//! the Python world.
//! - [Hjson](https://github.com/laktak/hjson-rust), a variant of JSON designed
//! to be readable and writable by humans.
//! - [BSON](https://github.com/zonyitoo/bson-rs), the data storage and network
//! transfer format used by MongoDB.
//! - [URL](https://github.com/nox/serde_urlencoded), the x-www-form-urlencoded
//! format.
//! - [XML](https://github.com/serde-rs/xml), the flexible machine-friendly W3C
//! standard. *(deserialization only)*
//! - [Envy](https://github.com/softprops/envy), a way to deserialize
//! environment variables into Rust structs. *(deserialization only)*
//! - [Redis](https://github.com/OneSignal/serde-redis), deserialize values from
//! Redis when using [redis-rs](https://crates.io/crates/redis).
//! *(deserialization only)*
#![doc(html_root_url="https://docs.serde.rs")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "unstable", feature(reflect_marker, unicode, nonzero, plugin, step_trait, zero_one))]
#![cfg_attr(feature = "unstable", feature(nonzero, inclusive_range, zero_one))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections, enumset))]
#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]
#![cfg_attr(feature = "clippy", allow(linkedlist))]
#![cfg_attr(any(not(feature = "std"), feature = "unstable"), allow(unused_variables, unused_imports, unused_features, dead_code))]
#![cfg_attr(feature = "clippy", allow(linkedlist, type_complexity))]
#![deny(missing_docs)]
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
extern crate collections;
#[cfg(all(feature = "unstable", feature = "alloc"))]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "unstable")]
extern crate core as actual_core;
#[cfg(feature = "std")]
mod core {
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
usize, f32, f64, char, str, num, slice, iter, cell};
usize, f32, f64, char, str, num, slice, iter, cell, default, result};
#[cfg(feature = "unstable")]
extern crate core;
#[cfg(feature = "unstable")]
pub use self::core::nonzero;
pub use actual_core::nonzero;
}
pub use ser::{Serialize, Serializer};
pub use de::{Deserialize, Deserializer};
#[cfg(not(feature = "std"))]
macro_rules! format {
($s:expr, $($rest:tt)*) => ($s)
}
#[macro_use]
mod macros;
pub mod bytes;
pub mod de;
#[cfg(feature = "std")]
#[doc(hidden)]
pub mod iter;
pub mod ser;
#[cfg(not(feature = "std"))]
#[cfg_attr(feature = "std", doc(hidden))]
pub mod error;
mod utils;
// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;
+54 -15
View File
@@ -32,9 +32,6 @@ macro_rules! forward_to_deserialize_helper {
(bool) => {
forward_to_deserialize_method!{deserialize_bool()}
};
(usize) => {
forward_to_deserialize_method!{deserialize_usize()}
};
(u8) => {
forward_to_deserialize_method!{deserialize_u8()}
};
@@ -47,9 +44,6 @@ macro_rules! forward_to_deserialize_helper {
(u64) => {
forward_to_deserialize_method!{deserialize_u64()}
};
(isize) => {
forward_to_deserialize_method!{deserialize_isize()}
};
(i8) => {
forward_to_deserialize_method!{deserialize_i8()}
};
@@ -92,6 +86,9 @@ macro_rules! forward_to_deserialize_helper {
(bytes) => {
forward_to_deserialize_method!{deserialize_bytes()}
};
(byte_buf) => {
forward_to_deserialize_method!{deserialize_byte_buf()}
};
(map) => {
forward_to_deserialize_method!{deserialize_map()}
};
@@ -121,28 +118,70 @@ macro_rules! forward_to_deserialize_helper {
};
}
/// Helper to forward `Deserializer` methods to `Deserializer::deserialize`.
/// Every given method ignores all arguments and forwards to `deserialize`.
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`; a
/// better approach is tracked in [serde-rs/serde#521][1].
// Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize
// documentation.
//
/// Helper macro when implementing the `Deserializer` part of a new data format
/// for Serde.
///
/// ```rust,ignore
/// Some `Deserializer` implementations for self-describing formats do not care
/// what hint the `Visitor` gives them, they just want to blindly call the
/// `Visitor` method corresponding to the data they can tell is in the input.
/// This requires repetitive implementations of all the `Deserializer` trait
/// methods.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// # impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// # fn deserialize<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor
/// # { unimplemented!() }
/// #
/// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// self.deserialize(visitor)
/// }
/// # forward_to_deserialize! {
/// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// # tuple_struct struct struct_field tuple enum ignored_any
/// # }
/// # }
/// # fn main() {}
/// ```
///
/// The `forward_to_deserialize!` macro implements these simple forwarding
/// methods so that they forward directly to `Deserializer::deserialize`. You
/// can choose which methods to forward.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// /* ... */
/// # let _ = visitor;
/// # unimplemented!()
/// }
///
/// forward_to_deserialize! {
/// bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
/// unit option seq seq_fixed_size bytes map unit_struct newtype_struct
/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any
/// }
/// }
/// # fn main() {}
/// ```
///
/// [1]: https://github.com/serde-rs/serde/issues/521
#[macro_export]
macro_rules! forward_to_deserialize {
($($func:ident)*) => {
+39 -29
View File
@@ -1,9 +1,3 @@
//! Implementations for all of Rust's builtin types. Tuples implement the `Serialize` trait if they
//! have at most 16 fields. Arrays implement the `Serialize` trait if their length is 32 or less.
//! You can always forward array serialization to slice serialization, which works for any length.
//! Long tuples are best replaced by tuple structs, for which you can use `derive(Serialize)`. In
//! that case the number of fields is irrelevant.
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
@@ -30,19 +24,18 @@ use collections::{
Vec,
};
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
use collections::enum_set::{CLike, EnumSet};
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
use collections::borrow::ToOwned;
#[cfg(feature = "std")]
use core::hash::{Hash, BuildHasher};
#[cfg(feature = "unstable")]
use core::iter;
#[cfg(feature = "std")]
use std::net;
#[cfg(feature = "unstable")]
use core::num;
#[cfg(feature = "unstable")]
use core::ops;
#[cfg(feature = "std")]
use std::path;
@@ -67,14 +60,13 @@ use core::marker::PhantomData;
use core::nonzero::{NonZero, Zeroable};
use super::{
Error,
Serialize,
SerializeMap,
SerializeSeq,
SerializeStruct,
SerializeTuple,
Serializer,
};
#[cfg(any(feature = "std", feature = "unstable"))]
use super::Error;
#[cfg(feature = "unstable")]
use super::Iterator;
@@ -82,25 +74,25 @@ use super::Iterator;
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident) => {
($ty:ty, $method:ident $($cast:tt)*) => {
impl Serialize for $ty {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
serializer.$method(*self)
serializer.$method(*self $($cast)*)
}
}
}
}
impl_visit!(bool, serialize_bool);
impl_visit!(isize, serialize_isize);
impl_visit!(isize, serialize_i64 as i64);
impl_visit!(i8, serialize_i8);
impl_visit!(i16, serialize_i16);
impl_visit!(i32, serialize_i32);
impl_visit!(i64, serialize_i64);
impl_visit!(usize, serialize_usize);
impl_visit!(usize, serialize_u64 as u64);
impl_visit!(u8, serialize_u8);
impl_visit!(u16, serialize_u16);
impl_visit!(u32, serialize_u32);
@@ -241,7 +233,7 @@ impl<'a, I> Serialize for Iterator<I>
// FIXME: use specialization to prevent invalidating the object in case of clonable iterators?
let iter = match self.0.borrow_mut().take() {
Some(iter) => iter.into_iter(),
None => return Err(S::Error::custom("Iterator used twice")),
None => return Err(Error::custom("Iterator used twice")),
};
let size = match iter.size_hint() {
(lo, Some(hi)) if lo == hi => Some(lo),
@@ -249,7 +241,7 @@ impl<'a, I> Serialize for Iterator<I>
};
let mut seq = try!(serializer.serialize_seq(size));
for e in iter {
try!(seq.serialize_element(e));
try!(seq.serialize_element(&e));
}
seq.end()
}
@@ -265,7 +257,7 @@ macro_rules! serialize_seq {
{
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self {
try!(seq.serialize_element(e));
try!(seq.serialize_element(&e));
}
seq.end()
}
@@ -286,7 +278,7 @@ impl<T> Serialize for BTreeSet<T>
serialize_seq!();
}
#[cfg(all(feature = "unstable", feature = "collections"))]
#[cfg(feature = "collections")]
impl<T> Serialize for EnumSet<T>
where T: Serialize + CLike
{
@@ -324,17 +316,33 @@ impl<T> Serialize for VecDeque<T>
#[cfg(feature = "unstable")]
impl<A> Serialize for ops::Range<A>
where A: Serialize + Clone + iter::Step + num::One,
for<'a> &'a A: ops::Add<&'a A, Output = A>,
where ops::Range<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
let mut seq = try!(serializer.serialize_seq(len));
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self.clone() {
try!(seq.serialize_element(e));
try!(seq.serialize_element(&e));
}
seq.end()
}
}
#[cfg(feature = "unstable")]
impl<A> Serialize for ops::RangeInclusive<A>
where ops::RangeInclusive<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self.clone() {
try!(seq.serialize_element(&e));
}
seq.end()
}
@@ -557,6 +565,7 @@ macro_rules! serialize_map {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
use super::SerializeMap;
let mut map = try!(serializer.serialize_map(Some(self.len())));
for (k, v) in self {
try!(map.serialize_key(k));
@@ -679,9 +688,10 @@ impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("Duration", 2));
try!(state.serialize_field("secs", self.as_secs()));
try!(state.serialize_field("nanos", self.subsec_nanos()));
try!(state.serialize_field("secs", &self.as_secs()));
try!(state.serialize_field("nanos", &self.subsec_nanos()));
state.end()
}
}
@@ -756,7 +766,7 @@ impl Serialize for path::Path {
{
match self.to_str() {
Some(s) => s.serialize(serializer),
None => Err(Error::invalid_value("Path contains invalid UTF-8 characters")),
None => Err(Error::custom("path contains invalid UTF-8 characters")),
}
}
}
+540 -191
View File
@@ -1,84 +1,248 @@
//! Generic serialization framework.
//! # For Developers who want to serialize objects
//! Implement the `Serialize` trait for the type of objects you want to serialize. Call methods of
//! the `serializer` object. For which methods to call and how to do so, look at the documentation
//! of the `Serializer` trait.
//! Generic data structure serialization framework.
//!
//! # For Serialization Format Developers
//! Implement the `Serializer` trait for a structure that contains fields that enable it to write
//! the serialization result to your target. When a method's argument is an object of type
//! `Serialize`, you can either forward the serializer object (`self`) or create a new one,
//! depending on the quirks of your format.
//! The two most important traits in this module are `Serialize` and
//! `Serializer`.
//!
//! - **A type that implements `Serialize` is a data structure** that can be
//! serialized to any data format supported by Serde, and conversely
//! - **A type that implements `Serializer` is a data format** that can
//! serialize any data structure supported by Serde.
//!
//! # The Serialize trait
//!
//! Serde provides `Serialize` implementations for many Rust primitive and
//! standard library types. The complete list is below. All of these can be
//! serialized using Serde out of the box.
//!
//! Additionally, Serde provides a procedural macro called `serde_derive` to
//! automatically generate `Serialize` implementations for structs and enums in
//! your program. See the [codegen section of the manual][codegen] for how to
//! use this.
//!
//! In rare cases it may be necessary to implement `Serialize` manually for some
//! type in your program. See the [Implementing `Serialize`][impl-serialize]
//! section of the manual for more about this.
//!
//! Third-party crates may provide `Serialize` implementations for types that
//! they expose. For example the `linked-hash-map` crate provides a
//! `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
//! provides an implementation of `Serialize` for it.
//!
//! # The Serializer trait
//!
//! `Serializer` implementations are provided by third-party crates, for example
//! [`serde_json`][serde_json], [`serde_yaml`][serde_yaml] and
//! [`bincode`][bincode].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data-formats].
//!
//! # Implementations of Serialize provided by Serde
//!
//! - **Primitive types**:
//! - bool
//! - isize, i8, i16, i32, i64
//! - usize, u8, u16, u32, u64
//! - f32, f64
//! - char
//! - str
//! - &T and &mut T
//! - **Compound types**:
//! - [T]
//! - [T; 0] through [T; 32]
//! - tuples up to size 16
//! - **Common standard library types**:
//! - String
//! - Option\<T\>
//! - Result\<T, E\>
//! - PhantomData\<T\>
//! - **Wrapper types**:
//! - Box\<T\>
//! - Rc\<T\>
//! - Arc\<T\>
//! - Cow\<'a, T\>
//! - **Collection types**:
//! - BTreeMap\<K, V\>
//! - BTreeSet\<T\>
//! - BinaryHeap\<T\>
//! - HashMap\<K, V, H\>
//! - HashSet\<T, H\>
//! - LinkedList\<T\>
//! - VecDeque\<T\>
//! - Vec\<T\>
//! - EnumSet\<T\> (unstable)
//! - Range\<T\> (unstable)
//! - RangeInclusive\<T\> (unstable)
//! - **Miscellaneous standard library types**:
//! - Duration
//! - Path
//! - PathBuf
//! - NonZero\<T\> (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
//! - SocketAddr
//! - SocketAddrV4
//! - SocketAddrV6
//!
//! [codegen]: https://serde.rs/codegen.html
//! [impl-serialize]: https://serde.rs/impl-serialize.html
//! [serde_json]: https://github.com/serde-rs/json
//! [serde_yaml]: https://github.com/dtolnay/serde-yaml
//! [bincode]: https://github.com/TyOverby/bincode
//! [data-formats]: https://serde.rs/#data-formats
#[cfg(feature = "std")]
use std::error;
#[cfg(not(feature = "std"))]
use error;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::String;
#[cfg(feature = "unstable")]
use core::marker::PhantomData;
#[cfg(feature = "unstable")]
use core::cell::RefCell;
pub mod impls;
use core::fmt::Display;
mod impls;
///////////////////////////////////////////////////////////////////////////////
/// `Error` is a trait that allows a `Serialize` to generically create a
/// `Serializer` error.
/// Trait used by `Serialize` implementations to generically construct errors
/// belonging to the `Serializer` against which they are currently running.
pub trait Error: Sized + error::Error {
/// Raised when there is a general error when serializing a type.
#[cfg(any(feature = "std", feature = "collections"))]
fn custom<T: Into<String>>(msg: T) -> Self;
/// Raised when there is a general error when serializing a type.
#[cfg(all(not(feature = "std"), not(feature = "collections")))]
fn custom<T: Into<&'static str>>(msg: T) -> Self;
/// Raised when a `Serialize` was passed an incorrect value.
fn invalid_value(msg: &str) -> Self {
Error::custom(format!("invalid value: {}", msg))
}
/// Raised when a `Serialize` implementation encounters a general error
/// while serializing a type.
///
/// The message should not be capitalized and should not end with a period.
///
/// For example, a filesystem `Path` may refuse to serialize itself if it
/// contains invalid UTF-8 data.
///
/// ```rust
/// # use serde::ser::{Serialize, Serializer, Error};
/// # struct Path;
/// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } }
/// impl Serialize for Path {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer
/// {
/// match self.to_str() {
/// Some(s) => s.serialize(serializer),
/// None => Err(Error::custom("path contains invalid UTF-8 characters")),
/// }
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self;
}
///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can be serialized by a `Serializer`.
/// An implementation of this trait is a **data structure** that can be
/// serialized into any data format supported by Serde.
///
/// Serde provides `Serialize` implementations for many Rust primitive and
/// standard library types. The complete list is [here][ser]. All of these can
/// be serialized using Serde out of the box.
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual][codegen] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`][impl-serialize]
/// section of the manual for more about this.
///
/// Third-party crates may provide `Serialize` implementations for types that
/// they expose. For example the `linked-hash-map` crate provides a
/// `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
/// provides an implementation of `Serialize` for it.
///
/// [ser]: https://docs.serde.rs/serde/ser/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [impl-serialize]: https://serde.rs/impl-serialize.html
pub trait Serialize {
/// Serializes this value into this serializer.
/// Serialize this value into the given Serde serializer.
///
/// See the [Implementing `Serialize`][impl-serialize] section of the manual
/// for more information about how to implement this method.
///
/// [impl-serialize]: https://serde.rs/impl-serialize.html
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer;
}
///////////////////////////////////////////////////////////////////////////////
/// A trait that describes a type that can serialize a stream of values into the underlying format.
/// An implementation of this trait is a **data format** that can serialize any
/// data structure supported by Serde.
///
/// # For `Serialize` Developers
/// Non-aggregate types like integers and strings can be serialized directly by calling the
/// appropriate function. For Aggregate types there's an initial `serialize_T` method that yields
/// a State object that you should not interact with. For each part of the aggregate there's a
/// `serialize_T_elt` method that allows you to pass values or key/value pairs. The types of the
/// values or the keys may change between calls, but the serialization format may not necessarily
/// accept it. The `serialize_T_elt` method also takes a mutable reference to the state object.
/// Make sure that you always use the same state object and only the state object that was returned
/// by the `serialize_T` method. Finally, when your object is done, call the `serialize_T_end`
/// method and pass the state object by value
/// The role of this trait is to define the serialization half of the Serde data
/// model, which is a way to categorize every Rust data structure into one of 28
/// possible types. Each method of the `Serializer` trait corresponds to one of
/// the types of the data model.
///
/// # For Serialization Format Developers
/// If your format has different situations where it accepts different types, create a
/// `Serializer` for each situation. You can create the sub-`Serializer` in one of the aggregate
/// `serialize_T` methods and return it as a state object. Remember to also set the corresponding
/// associated type `TState`. In the `serialize_T_elt` methods you will be given a mutable
/// reference to that state. You do not need to do any additional checks for the correctness of the
/// state object, as it is expected that the user will not modify it. Due to the generic nature
/// of the `Serialize` impls, modifying the object is impossible on stable Rust.
/// Implementations of `Serialize` map themselves into this data model by
/// invoking exactly one of the `Serializer` methods.
///
/// The types that make up the Serde data model are:
///
/// - 12 primitive types:
/// - bool
/// - i8, i16, i32, i64
/// - u8, u16, u32, u64
/// - f32, f64
/// - char
/// - string
/// - byte array - [u8]
/// - option
/// - either none or some value
/// - unit
/// - unit is the type of () in Rust
/// - unit_struct
/// - for example `struct Unit` or `PhantomData<T>`
/// - unit_variant
/// - the `E::A` and `E::B` in `enum E { A, B }`
/// - newtype_struct
/// - for example `struct Millimeters(u8)`
/// - newtype_variant
/// - the `E::N` in `enum E { N(u8) }`
/// - seq
/// - a dynamically sized sequence of values, for example `Vec<T>` or
/// `HashSet<T>`
/// - seq_fixed_size
/// - a statically sized sequence of values for which the size will be known
/// at deserialization time without looking at the serialized data, for
/// example `[u64; 10]`
/// - tuple
/// - for example `(u8,)` or `(String, u64, Vec<T>)`
/// - tuple_struct
/// - for example `struct Rgb(u8, u8, u8)`
/// - tuple_variant
/// - the `E::T` in `enum E { T(u8, u8) }`
/// - map
/// - for example `BTreeMap<K, V>`
/// - struct
/// - a key-value pairing in which the keys will be known at deserialization
/// time without looking at the serialized data, for example `struct S { r:
/// u8, g: u8, b: u8 }`
/// - struct_variant
/// - the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`
///
/// Many Serde serializers produce text or binary data as output, for example
/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as
/// output.
pub trait Serializer {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `Serializer` should set `Ok = ()`.
/// The output type produced by this `Serializer` during successful
/// serialization. Most serializers that produce text or binary output
/// should set `Ok = ()` and serialize into an `io::Write` or buffer
/// contained within the `Serializer` instance. Serializers that build
/// in-memory data structures may be simplified by using `Ok` to propagate
/// the data structure around.
type Ok;
/// The error type when some error occurs during serialization.
@@ -112,75 +276,85 @@ pub trait Serializer {
/// content of the struct variant.
type SerializeStructVariant: SerializeStructVariant<Ok=Self::Ok, Error=Self::Error>;
/// Serializes a `bool` value.
/// Serialize a `bool` value.
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
/// Serializes an `isize` value. If the format does not differentiate
/// between `isize` and `i64`, a reasonable implementation would be to cast
/// the value to `i64` and forward to `serialize_i64`.
fn serialize_isize(self, v: isize) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i8` value. If the format does not differentiate between
/// `i8` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
/// Serialize an `i8` value.
///
/// If the format does not differentiate between `i8` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i16` value. If the format does not differentiate between
/// `i16` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
/// Serialize an `i16` value.
///
/// If the format does not differentiate between `i16` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i32` value. If the format does not differentiate between
/// `i32` and `i64`, a reasonable implementation would be to cast the value
/// to `i64` and forward to `serialize_i64`.
/// Serialize an `i32` value.
///
/// If the format does not differentiate between `i32` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
/// Serializes an `i64` value.
/// Serialize an `i64` value.
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
/// Serializes a `usize` value. If the format does not differentiate between
/// `usize` and `u64`, a reasonable implementation would be to cast the
/// value to `u64` and forward to `serialize_u64`.
fn serialize_usize(self, v: usize) -> Result<Self::Ok, Self::Error>;
/// Serializes a `u8` value. If the format does not differentiate between
/// `u8` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
/// Serialize a `u8` value.
///
/// If the format does not differentiate between `u8` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
/// Serializes a `u16` value. If the format does not differentiate between
/// `u16` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
/// Serialize a `u16` value.
///
/// If the format does not differentiate between `u16` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
/// Serializes a `u32` value. If the format does not differentiate between
/// `u32` and `u64`, a reasonable implementation would be to cast the value
/// to `u64` and forward to `serialize_u64`.
/// Serialize a `u32` value.
///
/// If the format does not differentiate between `u32` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
/// `Serializes a `u64` value.
/// Serialize a `u64` value.
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
/// Serializes an `f32` value. If the format does not differentiate between
/// `f32` and `f64`, a reasonable implementation would be to cast the value
/// to `f64` and forward to `serialize_f64`.
/// Serialize an `f32` value.
///
/// If the format does not differentiate between `f32` and `f64`, a
/// reasonable implementation would be to cast the value to `f64` and
/// forward to `serialize_f64`.
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
/// Serializes an `f64` value.
/// Serialize an `f64` value.
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
/// Serializes a character. If the format does not support characters,
/// it is reasonable to serialize it as a single element `str` or a `u32`.
/// Serialize a character.
///
/// If the format does not support characters, it is reasonable to serialize
/// it as a single element `str` or a `u32`.
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
/// Serializes a `&str`.
/// Serialize a `&str`.
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error>;
/// Serialize a chunk of raw byte data.
///
/// Enables serializers to serialize byte slices more compactly or more
/// efficiently than other types of slices. If no efficient implementation
/// is available, a reasonable implementation would be to forward to
/// `serialize_seq`. If forwarded, the implementation looks usually just like this:
/// ```rust
/// `serialize_seq`. If forwarded, the implementation looks usually just
/// like this:
///
/// ```rust,ignore
/// let mut seq = self.serialize_seq(Some(value.len()))?;
/// for b in value {
/// seq.serialize_element(b)?;
@@ -189,19 +363,40 @@ pub trait Serializer {
/// ```
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error>;
/// Serializes a `()` value. It's reasonable to just not serialize anything.
/// Serialize a `None` value.
fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
/// Serialize a `Some(T)` value.
fn serialize_some<T: ?Sized + Serialize>(
self,
value: &T,
) -> Result<Self::Ok, Self::Error>;
/// Serialize a `()` value.
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
/// Serializes a unit struct value. A reasonable implementation would be to
/// forward to `serialize_unit`.
/// Serialize a unit struct like `struct Unit` or `PhantomData<T>`.
///
/// A reasonable implementation would be to forward to `serialize_unit`.
fn serialize_unit_struct(
self,
name: &'static str,
) -> Result<Self::Ok, Self::Error>;
/// Serializes a unit variant, otherwise known as a variant with no
/// arguments. A reasonable implementation would be to forward to
/// `serialize_unit`.
/// Serialize a unit variant like `E::A` in `enum E { A, B }`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant.
///
/// A reasonable implementation would be to forward to `serialize_unit`.
///
/// ```rust,ignore
/// match *self {
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
/// E::B => serializer.serialize_unit_variant("E", 1, "B"),
/// }
/// ```
fn serialize_unit_variant(
self,
name: &'static str,
@@ -209,74 +404,130 @@ pub trait Serializer {
variant: &'static str,
) -> Result<Self::Ok, Self::Error>;
/// Allows a tuple struct with a single element, also known as a newtype
/// struct, to be more efficiently serialized than a tuple struct with
/// multiple items. A reasonable implementation would be to forward to
/// `serialize_tuple_struct` or to just serialize the inner value without wrapping.
fn serialize_newtype_struct<T: Serialize>(
/// Serialize a newtype struct like `struct Millimeters(u8)`.
///
/// Serializers are encouraged to treat newtype structs as insignificant
/// wrappers around the data they contain. A reasonable implementation would
/// be to forward to `value.serialize(self)`.
///
/// ```rust,ignore
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
/// ```
fn serialize_newtype_struct<T: ?Sized + Serialize>(
self,
name: &'static str,
value: T,
value: &T,
) -> Result<Self::Ok, Self::Error>;
/// Allows a variant with a single item to be more efficiently serialized
/// than a variant with multiple items. A reasonable implementation would be
/// to forward to `serialize_tuple_variant`.
fn serialize_newtype_variant<T: Serialize>(
/// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant. The `value` is the data contained within this newtype variant.
///
/// ```rust,ignore
/// match *self {
/// E::N(ref n) => serializer.serialize_newtype_variant("E", 0, "N", n),
/// }
/// ```
fn serialize_newtype_variant<T: ?Sized + Serialize>(
self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: T,
value: &T,
) -> Result<Self::Ok, Self::Error>;
/// Serializes a `None` value.
fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
/// Serializes a `Some(...)` value.
fn serialize_some<T: Serialize>(
self,
value: T,
) -> Result<Self::Ok, Self::Error>;
/// Begins to serialize a sequence. This call must be followed by zero or
/// more calls to `serialize_seq_elt`, then a call to `serialize_seq_end`.
/// Begin to serialize a dynamically sized sequence. This call must be
/// followed by zero or more calls to `serialize_element`, then a call to
/// `end`.
///
/// The argument is the number of elements in the sequence, which may or may
/// not be computable before the sequence is iterated. Some serializers only
/// support sequences whose length is known up front.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq(
self,
len: Option<usize>,
) -> Result<Self::SerializeSeq, Self::Error>;
/// Begins to serialize a sequence whose length will be known at
/// deserialization time. This call must be followed by zero or more calls
/// to `serialize_seq_elt`, then a call to `serialize_seq_end`. A reasonable
/// implementation would be to forward to `serialize_seq`.
/// Begin to serialize a statically sized sequence whose length will be
/// known at deserialization time without looking at the serialized data.
/// This call must be followed by zero or more calls to `serialize_element`,
/// then a call to `end`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq_fixed_size(self.len())?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq_fixed_size(
self,
size: usize,
) -> Result<Self::SerializeSeq, Self::Error>;
/// Begins to serialize a tuple. This call must be followed by zero or more
/// calls to `serialize_tuple_elt`, then a call to `serialize_tuple_end`. A
/// reasonable implementation would be to forward to `serialize_seq`.
/// Begin to serialize a tuple. This call must be followed by zero or more
/// calls to `serialize_field`, then a call to `end`.
///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
fn serialize_tuple(
self,
len: usize,
) -> Result<Self::SerializeTuple, Self::Error>;
/// Begins to serialize a tuple struct. This call must be followed by zero
/// or more calls to `serialize_tuple_struct_elt`, then a call to
/// `serialize_tuple_struct_end`. A reasonable implementation would be to
/// forward to `serialize_tuple`.
/// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This
/// call must be followed by zero or more calls to `serialize_field`, then a
/// call to `end`.
///
/// The `name` is the name of the tuple struct and the `len` is the number
/// of data fields that will be serialized.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error>;
/// Begins to serialize a tuple variant. This call must be followed by zero
/// or more calls to `serialize_tuple_variant_elt`, then a call to
/// `serialize_tuple_variant_end`. A reasonable implementation would be to
/// forward to `serialize_tuple_struct`.
/// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8)
/// }`. This call must be followed by zero or more calls to
/// `serialize_field`, then a call to `end`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
fn serialize_tuple_variant(
self,
name: &'static str,
@@ -285,25 +536,65 @@ pub trait Serializer {
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error>;
/// Begins to serialize a map. This call must be followed by zero or more
/// calls to `serialize_map_key` and `serialize_map_value`, then a call to
/// `serialize_map_end`.
/// Begin to serialize a map. This call must be followed by zero or more
/// calls to `serialize_key` and `serialize_value`, then a call to `end`.
///
/// The argument is the number of elements in the map, which may or may not
/// be computable before the map is iterated. Some serializers only support
/// maps whose length is known up front.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_key(k)?;
/// map.serialize_value(v)?;
/// }
/// map.end()
/// ```
fn serialize_map(
self,
len: Option<usize>,
) -> Result<Self::SerializeMap, Self::Error>;
/// Begins to serialize a struct. This call must be followed by zero or more
/// calls to `serialize_struct_elt`, then a call to `serialize_struct_end`.
/// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`.
/// This call must be followed by zero or more calls to `serialize_field`,
/// then a call to `end`.
///
/// The `name` is the name of the struct and the `len` is the number of
/// data fields that will be serialized.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error>;
/// Begins to serialize a struct variant. This call must be followed by zero
/// or more calls to `serialize_struct_variant_elt`, then a call to
/// `serialize_struct_variant_end`.
/// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8,
/// g: u8, b: u8 } }`. This call must be followed by zero or more calls to
/// `serialize_field`, then a call to `end`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
fn serialize_struct_variant(
self,
name: &'static str,
@@ -315,130 +606,188 @@ pub trait Serializer {
/// Returned from `Serializer::serialize_seq` and
/// `Serializer::serialize_seq_fixed_size`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
pub trait SerializeSeq {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeSeq` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serializes a sequence element.
fn serialize_element<T: Serialize>(&mut self, value: T) -> Result<(), Self::Error>;
/// Serialize a sequence element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a sequence.
/// Finish serializing a sequence.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple`.
///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
pub trait SerializeTuple {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeTuple` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serializes a tuple element.
fn serialize_element<T: Serialize>(&mut self, value: T) -> Result<(), Self::Error>;
/// Serialize a tuple element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple.
/// Finish serializing a tuple.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple_struct`.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
pub trait SerializeTupleStruct {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeTupleStruct` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serializes a tuple struct element.
fn serialize_field<T: Serialize>(&mut self, value: T) -> Result<(), Self::Error>;
/// Serialize a tuple struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple struct.
/// Finish serializing a tuple struct.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
pub trait SerializeTupleVariant {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeTupleVariant` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serializes a tuple variant element.
fn serialize_field<T: Serialize>(&mut self, value: T) -> Result<(), Self::Error>;
/// Serialize a tuple variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a tuple variant.
/// Finish serializing a tuple variant.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_map`.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_key(k)?;
/// map.serialize_value(v)?;
/// }
/// map.end()
/// ```
pub trait SerializeMap {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeMap` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a map key.
fn serialize_key<T: Serialize>(&mut self, key: T) -> Result<(), Self::Error>;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error>;
/// Serialize a map value.
fn serialize_value<T: Serialize>(&mut self, value: T) -> Result<(), Self::Error>;
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a map.
/// Finish serializing a map.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_struct`.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
pub trait SerializeStruct {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeStruct` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serializes a struct field.
fn serialize_field<V: Serialize>(&mut self, key: &'static str, value: V) -> Result<(), Self::Error>;
/// Serialize a struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a struct.
/// Finish serializing a struct.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_struct_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
pub trait SerializeStructVariant {
/// Trickery to enforce correct use of the `Serialize` trait. Every
/// `SerializeStructVariant` should set `Ok = ()`.
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// The error type when some error occurs during serialization.
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a struct variant element.
fn serialize_field<V: Serialize>(&mut self, key: &'static str, value: V) -> Result<(), Self::Error>;
/// Serialize a struct variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>;
/// Finishes serializing a struct variant.
/// Finish serializing a struct variant.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// A wrapper type for iterators that implements `Serialize` for iterators whose items implement
/// `Serialize`. Don't use multiple times. Create new versions of this with the `iterator` function
/// every time you want to serialize an iterator.
/// A wrapper type for iterators that implements `Serialize` for iterators whose
/// items implement `Serialize`. Don't use multiple times. Create new versions
/// of this with the `serde::ser::iterator` function every time you want to
/// serialize an iterator.
#[cfg(feature = "unstable")]
pub struct Iterator<I>(RefCell<Option<I>>)
where <I as IntoIterator>::Item: Serialize,
I: IntoIterator;
/// Creates a temporary type that can be passed to any function expecting a `Serialize` and will
/// serialize the given iterator as a sequence
/// Create a wrapper type that can be passed to any function expecting a
/// `Serialize` and will serialize the given iterator as a sequence.
#[cfg(feature = "unstable")]
pub fn iterator<I>(iter: I) -> Iterator<I>
where <I as IntoIterator>::Item: Serialize,
+4 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen"
version = "0.9.0-rc1"
version = "0.9.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -27,3 +27,6 @@ serde_codegen_internals = { version = "=0.11.3", default-features = false, path
syn = { version = "0.10", features = ["aster", "visit"] }
syntex = { version = "^0.54.0", optional = true }
syntex_syntax = { version = "^0.54.0", optional = true }
[badges]
travis-ci = { repository = "serde-rs/serde" }
+125 -37
View File
@@ -1,5 +1,5 @@
use syn::{self, aster, Ident};
use quote::Tokens;
use quote::{self, Tokens};
use bound;
use internals::ast::{Body, Field, Item, Style, Variant};
@@ -36,7 +36,7 @@ pub fn expand_derive_deserialize(item: &syn::MacroInput) -> Result<Tokens, Strin
extern crate serde as _serde;
#[automatically_derived]
impl #impl_generics _serde::Deserialize for #ty #where_clause {
fn deserialize<__D>(deserializer: __D) -> ::std::result::Result<#ty, __D::Error>
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<#ty, __D::Error>
where __D: _serde::Deserializer
#body
}
@@ -158,11 +158,11 @@ fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) {
let phantom_types = generics.lifetimes.iter()
.map(|lifetime_def| {
let lifetime = &lifetime_def.lifetime;
quote!(::std::marker::PhantomData<& #lifetime ()>)
quote!(_serde::export::PhantomData<& #lifetime ()>)
}).chain(generics.ty_params.iter()
.map(|ty_param| {
let ident = &ty_param.ident;
quote!(::std::marker::PhantomData<#ident>)
quote!(_serde::export::PhantomData<#ident>)
}));
let all_params = generics.lifetimes.iter()
@@ -182,7 +182,7 @@ fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) {
Some(quote!(::<#(#ty_param_idents),*>))
};
let phantom_exprs = iter::repeat(quote!(::std::marker::PhantomData)).take(num_phantoms);
let phantom_exprs = iter::repeat(quote!(_serde::export::PhantomData)).take(num_phantoms);
(
quote! {
@@ -200,21 +200,27 @@ fn deserialize_unit_struct(
) -> Tokens {
let type_name = item_attrs.name().deserialize_name();
let expecting = format!("unit struct {}", type_ident);
quote!({
struct __Visitor;
impl _serde::de::Visitor for __Visitor {
type Value = #type_ident;
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
formatter.write_str(#expecting)
}
#[inline]
fn visit_unit<__E>(self) -> ::std::result::Result<#type_ident, __E>
fn visit_unit<__E>(self) -> _serde::export::Result<#type_ident, __E>
where __E: _serde::de::Error,
{
Ok(#type_ident)
}
#[inline]
fn visit_seq<__V>(self, _: __V) -> ::std::result::Result<#type_ident, __V::Error>
fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#type_ident, __V::Error>
where __V: _serde::de::SeqVisitor,
{
Ok(#type_ident)
@@ -242,6 +248,10 @@ fn deserialize_tuple(
Some(variant_ident) => quote!(#type_ident::#variant_ident),
None => quote!(#type_ident),
};
let expecting = match variant_ident {
Some(variant_ident) => format!("tuple variant {}::{}", type_ident, variant_ident),
None => format!("tuple struct {}", type_ident),
};
let nfields = fields.len();
@@ -287,10 +297,14 @@ fn deserialize_tuple(
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
type Value = #ty;
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
formatter.write_str(#expecting)
}
#visit_newtype_struct
#[inline]
fn visit_seq<__V>(self, #visitor_var: __V) -> ::std::result::Result<#ty, __V::Error>
fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result<#ty, __V::Error>
where __V: _serde::de::SeqVisitor
{
#visit_seq
@@ -310,6 +324,11 @@ fn deserialize_seq(
) -> Tokens {
let vars = (0..fields.len()).map(field_i as fn(_) -> _);
let deserialized_count = fields.iter()
.filter(|field| !field.attrs.skip_deserializing())
.count();
let expecting = format!("tuple of {} elements", deserialized_count);
let mut index_in_seq = 0usize;
let let_values = vars.clone().zip(fields)
.map(|(var, field)| {
@@ -338,7 +357,7 @@ fn deserialize_seq(
let #var = match #visit {
Some(value) => { value },
None => {
return Err(_serde::de::Error::invalid_length(#index_in_seq));
return Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
}
};
};
@@ -389,7 +408,7 @@ fn deserialize_newtype_struct(
};
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> ::std::result::Result<Self::Value, __E::Error>
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer,
{
Ok(#type_path(#value))
@@ -413,6 +432,10 @@ fn deserialize_struct(
Some(variant_ident) => quote!(#type_ident::#variant_ident),
None => quote!(#type_ident),
};
let expecting = match variant_ident {
Some(variant_ident) => format!("struct variant {}::{}", type_ident, variant_ident),
None => format!("struct {}", type_ident),
};
let visit_seq = deserialize_seq(
type_ident,
@@ -457,15 +480,19 @@ fn deserialize_struct(
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
type Value = #ty;
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
formatter.write_str(#expecting)
}
#[inline]
fn visit_seq<__V>(self, #visitor_var: __V) -> ::std::result::Result<#ty, __V::Error>
fn visit_seq<__V>(self, #visitor_var: __V) -> _serde::export::Result<#ty, __V::Error>
where __V: _serde::de::SeqVisitor
{
#visit_seq
}
#[inline]
fn visit_map<__V>(self, mut visitor: __V) -> ::std::result::Result<#ty, __V::Error>
fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result<#ty, __V::Error>
where __V: _serde::de::MapVisitor
{
#visit_map
@@ -489,24 +516,27 @@ fn deserialize_item_enum(
let type_name = item_attrs.name().deserialize_name();
let variant_names_idents = variants.iter()
let expecting = format!("enum {}", type_ident);
let variant_names_idents: Vec<_> = variants.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
.collect();
let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
quote! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let variant_visitor = deserialize_field_visitor(
variant_names_idents,
item_attrs,
true,
);
let variant_names = variants.iter().map(|variant| variant.attrs.name().deserialize_name());
let variants_stmt = quote! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
};
// Match arms to extract a variant from a string
let variant_arms = variants.iter()
.enumerate()
@@ -555,7 +585,11 @@ fn deserialize_item_enum(
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
type Value = #ty;
fn visit_enum<__V>(self, visitor: __V) -> ::std::result::Result<#ty, __V::Error>
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
formatter.write_str(#expecting)
}
fn visit_enum<__V>(self, visitor: __V) -> _serde::export::Result<#ty, __V::Error>
where __V: _serde::de::EnumVisitor,
{
#match_variant
@@ -648,7 +682,8 @@ fn deserialize_field_visitor(
item_attrs: &attr::Item,
is_variant: bool,
) -> Tokens {
let field_names = fields.iter().map(|&(ref name, _)| name);
let field_strs = fields.iter().map(|&(ref name, _)| name);
let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name));
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() {
@@ -657,13 +692,34 @@ fn deserialize_field_visitor(
Some(quote!(__ignore,))
};
let visit_index = if is_variant {
let variant_indices = 0u32..;
let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
Some(quote! {
fn visit_u32<__E>(self, value: u32) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error
{
match value {
#(
#variant_indices => Ok(__Field::#field_idents),
)*
_ => Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(value as u64),
&#fallthrough_msg))
}
}
})
} else {
None
};
let fallthrough_arm = if is_variant {
quote! {
Err(_serde::de::Error::unknown_variant(value))
Err(_serde::de::Error::unknown_variant(value, VARIANTS))
}
} else if item_attrs.deny_unknown_fields() {
quote! {
Err(_serde::de::Error::unknown_field(value))
Err(_serde::de::Error::unknown_field(value, FIELDS))
}
} else {
quote! {
@@ -671,6 +727,16 @@ fn deserialize_field_visitor(
}
};
let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() {
Some(quote! {
// TODO https://github.com/serde-rs/serde/issues/666
// update this to use str::from_utf8(value).unwrap_or("") on no_std
let value = &_serde::export::from_utf8_lossy(value);
})
} else {
None
};
quote! {
#[allow(non_camel_case_types)]
enum __Field {
@@ -680,7 +746,7 @@ fn deserialize_field_visitor(
impl _serde::Deserialize for __Field {
#[inline]
fn deserialize<__D>(deserializer: __D) -> ::std::result::Result<__Field, __D::Error>
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<__Field, __D::Error>
where __D: _serde::Deserializer,
{
struct __FieldVisitor;
@@ -688,16 +754,36 @@ fn deserialize_field_visitor(
impl _serde::de::Visitor for __FieldVisitor {
type Value = __Field;
fn visit_str<__E>(self, value: &str) -> ::std::result::Result<__Field, __E>
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
formatter.write_str("field name")
}
#visit_index
fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error
{
match value {
#(
#field_names => Ok(__Field::#field_idents),
#field_strs => Ok(__Field::#field_idents),
)*
_ => #fallthrough_arm
}
}
fn visit_bytes<__E>(self, value: &[u8]) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error
{
match value {
#(
#field_bytes => Ok(__Field::#field_idents),
)*
_ => {
#bytes_to_str
#fallthrough_arm
}
}
}
}
deserializer.deserialize_struct_field(__FieldVisitor)
@@ -713,12 +799,19 @@ fn deserialize_struct_visitor(
fields: &[Field],
item_attrs: &attr::Item,
) -> (Tokens, Tokens, Tokens) {
let field_names_idents = fields.iter()
let field_names_idents: Vec<_> = fields.iter()
.enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
.collect();
let fields_stmt = {
let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
quote! {
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
}
};
let field_visitor = deserialize_field_visitor(
field_names_idents,
item_attrs,
@@ -733,11 +826,6 @@ fn deserialize_struct_visitor(
item_attrs,
);
let field_names = fields.iter().map(|field| field.attrs.name().deserialize_name());
let fields_stmt = quote! {
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
};
(field_visitor, fields_stmt, visit_map)
}
@@ -893,18 +981,18 @@ fn wrap_deserialize_with(
quote! {
struct __SerdeDeserializeWithStruct #impl_generics #where_clause {
value: #field_ty,
phantom: ::std::marker::PhantomData<#phantom_ty>,
phantom: _serde::export::PhantomData<#phantom_ty>,
}
},
quote! {
impl #impl_generics _serde::Deserialize for #wrapper_ty #where_clause {
fn deserialize<__D>(__d: __D) -> ::std::result::Result<Self, __D::Error>
fn deserialize<__D>(__d: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer
{
let value = try!(#deserialize_with(__d));
Ok(__SerdeDeserializeWithStruct {
value: value,
phantom: ::std::marker::PhantomData,
phantom: _serde::export::PhantomData,
})
}
}
@@ -916,7 +1004,7 @@ fn wrap_deserialize_with(
fn expr_is_missing(attrs: &attr::Field) -> Tokens {
match *attrs.default() {
attr::FieldDefault::Default => {
return quote!(::std::default::Default::default());
return quote!(_serde::export::Default::default());
}
attr::FieldDefault::Path(ref path) => {
return quote!(#path());
@@ -928,7 +1016,7 @@ fn expr_is_missing(attrs: &attr::Field) -> Tokens {
match attrs.deserialize_with() {
None => {
quote! {
try!(visitor.missing_field(#name))
try!(_serde::de::private::missing_field(#name))
}
}
Some(_) => {
-1
View File
@@ -12,7 +12,6 @@ extern crate serde_codegen_internals as internals;
extern crate syntex;
#[cfg(feature = "with-syntex")]
#[macro_use]
extern crate syntex_syntax as syntax;
extern crate syn;
+5 -5
View File
@@ -30,7 +30,7 @@ pub fn expand_derive_serialize(item: &syn::MacroInput) -> Result<Tokens, String>
extern crate serde as _serde;
#[automatically_derived]
impl #impl_generics _serde::Serialize for #ty #where_clause {
fn serialize<__S>(&self, _serializer: __S) -> ::std::result::Result<__S::Ok, __S::Error>
fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#body
@@ -257,10 +257,10 @@ fn serialize_variant(
let variant_name = variant.attrs.name().serialize_name();
if variant.attrs.skip_serializing() {
let skipped_msg = format!("The enum variant {}::{} cannot be serialized",
let skipped_msg = format!("the enum variant {}::{} cannot be serialized",
type_ident, variant_ident);
let skipped_err = quote! {
Err(_serde::ser::Error::invalid_value(#skipped_msg))
Err(_serde::ser::Error::custom(#skipped_msg))
};
let fields_pat = match variant.style {
Style::Unit => quote!(),
@@ -541,14 +541,14 @@ fn wrap_serialize_with(
}
impl #wrapper_generics _serde::Serialize for #wrapper_ty #where_clause {
fn serialize<__S>(&self, __s: __S) -> ::std::result::Result<__S::Ok, __S::Error>
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#path(self.value, __s)
}
}
__SerializeWith {
&__SerializeWith {
value: #value,
phantom: ::std::marker::PhantomData::<#item_ty>,
}
+3
View File
@@ -16,3 +16,6 @@ unstable-testing = ["clippy"]
[dependencies]
clippy = { version = "^0.*", optional = true }
syn = "0.10"
[badges]
travis-ci = { repository = "serde-rs/serde" }
+7 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "0.9.0-rc1"
version = "0.9.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -10,12 +10,15 @@ documentation = "https://serde.rs/codegen.html"
keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
[lib]
name = "serde_derive"
proc-macro = true
[dependencies.serde_codegen]
version = "=0.9.0-rc1"
version = "=0.9.0"
path = "../serde_codegen"
default-features = false
features = ["with-syn"]
@@ -23,5 +26,5 @@ features = ["with-syn"]
[dev-dependencies]
compiletest_rs = "^0.2.0"
fnv = "1.0"
serde = { version = "0.9.0-rc1", path = "../serde" }
serde_test = { version = "0.9.0-rc1", path = "../serde_test" }
serde = { version = "0.9.0", path = "../serde" }
serde_test = { version = "0.9.0", path = "../serde_test" }
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "serde_derive_tests_no_std"
version = "0.9.0"
publish = false
[dependencies]
serde = { path = "../../serde", default-features = false }
serde_derive = { path = ".." }
+50
View File
@@ -0,0 +1,50 @@
#![feature(lang_items, start, libc)]
#![no_std]
extern crate libc;
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
0
}
#[lang = "eh_personality"]
#[no_mangle]
pub extern fn rust_eh_personality() {}
#[lang = "eh_unwind_resume"]
#[no_mangle]
pub extern fn rust_eh_unwind_resume() {}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32) -> ! {
loop {}
}
//////////////////////////////////////////////////////////////////////////////
#[macro_use]
extern crate serde_derive;
#[derive(Serialize, Deserialize)]
struct Unit;
#[derive(Serialize, Deserialize)]
struct Newtype(u8);
#[derive(Serialize, Deserialize)]
struct Tuple(u8, u8);
#[derive(Serialize, Deserialize)]
struct Struct { f: u8 }
#[derive(Serialize, Deserialize)]
enum Enum {
Unit,
Newtype(u8),
Tuple(u8, u8),
Struct { f: u8 },
}
+5 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "0.9.0-rc1"
version = "0.9.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -12,4 +12,7 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[dependencies]
serde = { version = "0.9.0-rc1", path = "../serde" }
serde = { version = "0.9.0", path = "../serde" }
[badges]
travis-ci = { repository = "serde-rs/serde" }
+71 -75
View File
@@ -3,6 +3,7 @@ use std::iter;
use serde::de::{
self,
Deserialize,
DeserializeSeed,
EnumVisitor,
MapVisitor,
SeqVisitor,
@@ -42,7 +43,7 @@ impl<I> Deserializer<I>
Err(Error::UnexpectedToken(token))
}
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -160,6 +161,10 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize_byte_buf<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize_ignored_any<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
@@ -220,26 +225,16 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize_usize<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize_isize<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: de::Visitor {
self.deserialize(visitor)
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
where V: Visitor,
{
match self.tokens.next() {
Some(Token::Bool(v)) => visitor.visit_bool(v),
Some(Token::Isize(v)) => visitor.visit_isize(v),
Some(Token::I8(v)) => visitor.visit_i8(v),
Some(Token::I16(v)) => visitor.visit_i16(v),
Some(Token::I32(v)) => visitor.visit_i32(v),
Some(Token::I64(v)) => visitor.visit_i64(v),
Some(Token::Usize(v)) => visitor.visit_usize(v),
Some(Token::U8(v)) => visitor.visit_u8(v),
Some(Token::U16(v)) => visitor.visit_u16(v),
Some(Token::U32(v)) => visitor.visit_u32(v),
@@ -250,10 +245,11 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
Some(Token::Str(v)) => visitor.visit_str(v),
Some(Token::String(v)) => visitor.visit_string(v),
Some(Token::Bytes(v)) => visitor.visit_bytes(v),
Some(Token::ByteBuf(v)) => visitor.visit_byte_buf(v),
Some(Token::Option(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::UnitStruct(name)) => visitor.visit_unit_struct(name),
Some(Token::UnitStruct(_name)) => visitor.visit_unit(),
Some(Token::SeqStart(len)) => {
self.visit_seq(len, visitor)
}
@@ -267,7 +263,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
self.visit_map(Some(len), visitor)
}
Some(token) => Err(Error::UnexpectedToken(token)),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -290,7 +286,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
visitor.visit_none()
}
Some(_) => visitor.visit_some(self),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -320,7 +316,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
let token = self.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => { return Err(Error::EndOfStream); }
None => { return Err(Error::EndOfTokens); }
}
}
@@ -337,7 +333,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
}
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -356,7 +352,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
}
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -371,7 +367,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
self.visit_array(len, visitor)
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -406,7 +402,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
self.visit_tuple_struct(len, visitor)
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -450,7 +446,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
}
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -474,7 +470,7 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
self.visit_map(Some(fields.len()), visitor)
}
Some(_) => self.deserialize(visitor),
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
}
@@ -491,21 +487,21 @@ impl<'a, I> SeqVisitor for DeserializerSeqVisitor<'a, I>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::SeqSep) => {
self.de.tokens.next();
self.len = self.len.map(|len| len - 1);
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::SeqEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -527,21 +523,21 @@ impl<'a, I> SeqVisitor for DeserializerArrayVisitor<'a, I>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::SeqSep) => {
self.de.tokens.next();
self.len -= 1;
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::SeqEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -562,21 +558,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleVisitor<'a, I>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::TupleSep) => {
self.de.tokens.next();
self.len -= 1;
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::TupleEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -597,21 +593,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleStructVisitor<'a, I>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::TupleStructSep) => {
self.de.tokens.next();
self.len -= 1;
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::TupleStructEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -632,21 +628,21 @@ impl<'a, I> SeqVisitor for DeserializerVariantSeqVisitor<'a, I>
{
type Error = Error;
fn visit<T>(&mut self) -> Result<Option<T>, Error>
where T: Deserialize,
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::EnumSeqSep) => {
self.de.tokens.next();
self.len = self.len.map(|len| len - 1);
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::EnumSeqEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -668,28 +664,28 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where K: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::MapSep) => {
self.de.tokens.next();
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::MapEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
fn visit_value<V>(&mut self) -> Result<V, Error>
where V: Deserialize,
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where V: DeserializeSeed,
{
Deserialize::deserialize(&mut *self.de)
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -710,28 +706,28 @@ impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where K: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::StructSep) => {
self.de.tokens.next();
self.len = self.len.saturating_sub(1);
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::StructEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
fn visit_value<V>(&mut self) -> Result<V, Error>
where V: Deserialize,
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where V: DeserializeSeed,
{
Deserialize::deserialize(&mut *self.de)
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -751,8 +747,8 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
type Error = Error;
type Variant = Self;
fn visit_variant<V>(self) -> Result<(V, Self), Error>
where V: Deserialize,
fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error>
where V: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::EnumUnit(_, v))
@@ -760,14 +756,14 @@ impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
| Some(&Token::EnumSeqStart(_, v, _))
| Some(&Token::EnumMapStart(_, v, _)) => {
let de = v.into_deserializer();
let value = try!(Deserialize::deserialize(de));
let value = try!(seed.deserialize(de));
Ok((value, self))
}
Some(_) => {
let value = try!(Deserialize::deserialize(&mut *self.de));
let value = try!(seed.deserialize(&mut *self.de));
Ok((value, self))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
}
@@ -786,22 +782,22 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
Some(_) => {
Deserialize::deserialize(self.de)
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
fn visit_newtype<T>(self) -> Result<T, Self::Error>
where T: Deserialize,
fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where T: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::EnumNewType(_, _)) => {
self.de.tokens.next();
Deserialize::deserialize(self.de)
seed.deserialize(self.de)
}
Some(_) => {
Deserialize::deserialize(self.de)
seed.deserialize(self.de)
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -832,7 +828,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
Some(_) => {
de::Deserializer::deserialize(self.de, visitor)
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
@@ -863,7 +859,7 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
Some(_) => {
de::Deserializer::deserialize(self.de, visitor)
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
}
@@ -880,28 +876,28 @@ impl<'a, I> MapVisitor for DeserializerVariantMapVisitor<'a, I>
{
type Error = Error;
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
where K: Deserialize,
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where K: DeserializeSeed,
{
match self.de.tokens.peek() {
Some(&Token::EnumMapSep) => {
self.de.tokens.next();
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
Deserialize::deserialize(&mut *self.de).map(Some)
seed.deserialize(&mut *self.de).map(Some)
}
Some(&Token::EnumMapEnd) => Ok(None),
Some(_) => {
let token = self.de.tokens.next().unwrap();
Err(Error::UnexpectedToken(token))
}
None => Err(Error::EndOfStream),
None => Err(Error::EndOfTokens),
}
}
fn visit_value<V>(&mut self) -> Result<V, Error>
where V: Deserialize,
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where V: DeserializeSeed,
{
Deserialize::deserialize(&mut *self.de)
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> (usize, Option<usize>) {
+21 -60
View File
@@ -1,4 +1,5 @@
use std::{error, fmt};
use std::error;
use std::fmt::{self, Display};
use serde::{ser, de};
@@ -6,82 +7,42 @@ use token::Token;
#[derive(Clone, PartialEq, Debug)]
pub enum Error {
// Shared
Custom(String),
InvalidValue(String),
// De
EndOfStream,
InvalidType(de::Type),
InvalidLength(usize),
UnknownVariant(String),
UnknownField(String),
MissingField(&'static str),
DuplicateField(&'static str),
Message(String),
InvalidName(&'static str),
UnexpectedToken(Token<'static>),
EndOfTokens,
}
impl ser::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Error {
Error::Custom(msg.into())
}
fn invalid_value(msg: &str) -> Error {
Error::InvalidValue(msg.to_owned())
fn custom<T: Display>(msg: T) -> Error {
Error::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: Into<String>>(msg: T) -> Error {
Error::Custom(msg.into())
}
fn end_of_stream() -> Error {
Error::EndOfStream
}
fn invalid_type(ty: de::Type) -> Error {
Error::InvalidType(ty)
}
fn invalid_value(msg: &str) -> Error {
Error::InvalidValue(msg.to_owned())
}
fn invalid_length(len: usize) -> Error {
Error::InvalidLength(len)
}
fn unknown_variant(variant: &str) -> Error {
Error::UnknownVariant(variant.to_owned())
}
fn unknown_field(field: &str) -> Error {
Error::UnknownField(field.to_owned())
}
fn missing_field(field: &'static str) -> Error {
Error::MissingField(field)
}
fn duplicate_field(field: &'static str) -> Error {
Error::DuplicateField(field)
fn custom<T: Display>(msg: T) -> Error {
Error::Message(msg.to_string())
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(format!("{:?}", self).as_ref())
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Message(ref msg) => formatter.write_str(msg),
Error::InvalidName(name) => write!(formatter, "invalid name `{}`", name),
Error::UnexpectedToken(_) => formatter.write_str("unexpected token"),
Error::EndOfTokens => formatter.write_str("end of tokens"),
}
}
}
impl error::Error for Error {
fn description(&self) -> &str {
"Serde Error"
}
fn cause(&self) -> Option<&error::Error> {
None
match *self {
Error::Message(ref msg) => msg,
Error::InvalidName(_) => "invalid name",
Error::UnexpectedToken(_) => "unexpected token",
Error::EndOfTokens => "end of tokens",
}
}
}
+18 -28
View File
@@ -46,11 +46,6 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(())
}
fn serialize_isize(self, v: isize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Isize(v)));
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::I8(v)));
Ok(())
@@ -71,11 +66,6 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(())
}
fn serialize_usize(self, v: usize) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::Usize(v)));
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<(), Error> {
assert_eq!(self.tokens.next(), Some(&Token::U8(v)));
Ok(())
@@ -139,20 +129,20 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(())
}
fn serialize_newtype_struct<T>(self,
name: &'static str,
value: T) -> Result<(), Error>
fn serialize_newtype_struct<T: ?Sized>(self,
name: &'static str,
value: &T) -> Result<(), Error>
where T: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name)));
value.serialize(self)
}
fn serialize_newtype_variant<T>(self,
name: &str,
_variant_index: usize,
variant: &str,
value: T) -> Result<(), Error>
fn serialize_newtype_variant<T: ?Sized>(self,
name: &str,
_variant_index: usize,
variant: &str,
value: &T) -> Result<(), Error>
where T: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant)));
@@ -164,8 +154,8 @@ impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
Ok(())
}
fn serialize_some<V>(self, value: V) -> Result<(), Error>
where V: Serialize,
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
where T: Serialize,
{
assert_eq!(self.tokens.next(), Some(&Token::Option(true)));
value.serialize(self)
@@ -228,7 +218,7 @@ impl<'s, 'a, I> ser::SerializeSeq for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
@@ -247,7 +237,7 @@ impl<'s, 'a, I> ser::SerializeTuple for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_element<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::TupleSep));
@@ -266,7 +256,7 @@ impl<'s, 'a, I> ser::SerializeTupleStruct for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep));
@@ -285,7 +275,7 @@ impl<'s, 'a, I> ser::SerializeTupleVariant for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_field<T>(&mut self, value: T) -> Result<(), Error>
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where T: Serialize
{
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep));
@@ -304,12 +294,12 @@ impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_key<T>(&mut self, key: T) -> Result<(), Self::Error> where T: Serialize {
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::MapSep));
key.serialize(&mut **self)
}
fn serialize_value<T>(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize {
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
value.serialize(&mut **self)
}
@@ -325,7 +315,7 @@ impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::StructSep));
try!(key.serialize(&mut **self));
value.serialize(&mut **self)
@@ -343,7 +333,7 @@ impl<'s, 'a, I> ser::SerializeStructVariant for &'s mut Serializer<'a, I>
type Ok = ();
type Error = Error;
fn serialize_field<V>(&mut self, key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep));
try!(key.serialize(&mut **self));
value.serialize(&mut **self)
+1 -2
View File
@@ -1,12 +1,10 @@
#[derive(Clone, PartialEq, Debug)]
pub enum Token<'a> {
Bool(bool),
Isize(isize),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
Usize(usize),
U8(u8),
U16(u16),
U32(u32),
@@ -17,6 +15,7 @@ pub enum Token<'a> {
Str(&'a str),
String(String),
Bytes(&'a [u8]),
ByteBuf(Vec<u8>),
Option(bool),
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_testing"
version = "0.9.0-rc1"
version = "0.9.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+9 -9
View File
@@ -145,7 +145,7 @@ fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
&[
Token::EnumMapStart("DefaultEnum", "Struct", 5),
Token::EnumMapStart("DefaultEnum", "Struct", 3),
Token::EnumMapSep,
Token::Str("a1"),
@@ -174,7 +174,7 @@ fn test_default_enum() {
assert_de_tokens(
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
&[
Token::EnumMapStart("DefaultEnum", "Struct", 5),
Token::EnumMapStart("DefaultEnum", "Struct", 3),
Token::EnumMapSep,
Token::Str("a1"),
@@ -343,7 +343,7 @@ fn test_ignore_unknown() {
Token::StructSep,
Token::Str("whoops"),
],
Error::UnknownField("whoops".to_owned())
Error::Message("unknown field `whoops`, expected `a1`".to_owned())
);
}
@@ -905,7 +905,7 @@ fn test_missing_renamed_field_struct() {
Token::StructEnd,
],
Error::MissingField("a3"),
Error::Message("missing field `a3`".to_owned()),
);
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
@@ -918,7 +918,7 @@ fn test_missing_renamed_field_struct() {
Token::StructEnd,
],
Error::MissingField("a5"),
Error::Message("missing field `a5`".to_owned()),
);
}
@@ -930,7 +930,7 @@ fn test_missing_renamed_field_enum() {
Token::EnumMapEnd,
],
Error::MissingField("b"),
Error::Message("missing field `b`".to_owned()),
);
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
@@ -943,7 +943,7 @@ fn test_missing_renamed_field_enum() {
Token::EnumMapEnd,
],
Error::MissingField("d"),
Error::Message("missing field `d`".to_owned()),
);
}
@@ -962,7 +962,7 @@ fn test_invalid_length_enum() {
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
Error::Message("invalid length 1, expected tuple of 3 elements".to_owned()),
);
assert_de_tokens_error::<InvalidLengthEnum>(
&[
@@ -971,6 +971,6 @@ fn test_invalid_length_enum() {
Token::I32(1),
Token::EnumSeqEnd,
],
Error::InvalidLength(1),
Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()),
);
}
+2
View File
@@ -15,6 +15,7 @@ fn test_bytes() {
fn test_byte_buf() {
let empty = ByteBuf::new();
assert_tokens(&empty, &[Token::Bytes(b"")]);
assert_de_tokens(&empty, &[Token::ByteBuf(Vec::new())]);
assert_de_tokens(&empty, &[Token::Str("")]);
assert_de_tokens(&empty, &[Token::String(String::new())]);
assert_de_tokens(&empty, &[
@@ -28,6 +29,7 @@ fn test_byte_buf() {
let buf = ByteBuf::from(vec![65, 66, 67]);
assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
assert_de_tokens(&buf, &[Token::ByteBuf(vec![65, 66, 67])]);
assert_de_tokens(&buf, &[Token::Str("ABC")]);
assert_de_tokens(&buf, &[Token::String("ABC".to_owned())]);
assert_de_tokens(&buf, &[
+26 -24
View File
@@ -3,7 +3,7 @@ use std::net;
use std::path::PathBuf;
use std::time::Duration;
use serde::de::{Deserialize, Type};
use serde::Deserialize;
extern crate fnv;
use self::fnv::FnvHasher;
@@ -155,12 +155,10 @@ declare_tests! {
false => &[Token::Bool(false)],
}
test_isize {
0isize => &[Token::Isize(0)],
0isize => &[Token::I8(0)],
0isize => &[Token::I16(0)],
0isize => &[Token::I32(0)],
0isize => &[Token::I64(0)],
0isize => &[Token::Usize(0)],
0isize => &[Token::U8(0)],
0isize => &[Token::U16(0)],
0isize => &[Token::U32(0)],
@@ -169,14 +167,12 @@ declare_tests! {
0isize => &[Token::F64(0.)],
}
test_ints {
0isize => &[Token::Isize(0)],
0i8 => &[Token::I8(0)],
0i16 => &[Token::I16(0)],
0i32 => &[Token::I32(0)],
0i64 => &[Token::I64(0)],
}
test_uints {
0usize => &[Token::Usize(0)],
0u8 => &[Token::U8(0)],
0u16 => &[Token::U16(0)],
0u32 => &[Token::U32(0)],
@@ -774,6 +770,20 @@ declare_tests! {
Token::EnumMapEnd,
],
}
test_enum_unit_usize {
Enum::Unit => &[
Token::EnumStart("Enum"),
Token::U32(0),
Token::Unit,
],
}
test_enum_unit_bytes {
Enum::Unit => &[
Token::EnumStart("Enum"),
Token::Bytes(b"Unit"),
Token::Unit,
],
}
test_box {
Box::new(0i32) => &[Token::I32(0)],
}
@@ -849,7 +859,7 @@ declare_error_tests! {
Token::StructSep,
Token::Str("d"),
],
Error::UnknownField("d".to_owned()),
Error::Message("unknown field `d`, expected `a`".to_owned()),
}
test_skipped_field_is_unknown<StructDenyUnknown> {
&[
@@ -857,7 +867,7 @@ declare_error_tests! {
Token::StructSep,
Token::Str("b"),
],
Error::UnknownField("b".to_owned()),
Error::Message("unknown field `b`, expected `a`".to_owned()),
}
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
&[
@@ -865,25 +875,25 @@ declare_error_tests! {
Token::StructSep,
Token::Str("a"),
],
Error::UnknownField("a".to_owned()),
Error::Message("unknown field `a`, there are no fields".to_owned()),
}
test_unknown_variant<Enum> {
&[
Token::EnumUnit("Enum", "Foo"),
],
Error::UnknownVariant("Foo".to_owned()),
Error::Message("unknown variant `Foo`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()),
}
test_enum_skipped_variant<Enum> {
&[
Token::EnumUnit("Enum", "Skipped"),
],
Error::UnknownVariant("Skipped".to_owned()),
Error::Message("unknown variant `Skipped`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()),
}
test_enum_skip_all<EnumSkipAll> {
&[
Token::EnumUnit("EnumSkipAll", "Skipped"),
],
Error::UnknownVariant("Skipped".to_owned()),
Error::Message("unknown variant `Skipped`, there are no variants".to_owned()),
}
test_struct_seq_too_long<Struct> {
&[
@@ -904,7 +914,7 @@ declare_error_tests! {
Token::MapSep,
Token::Str("a"),
],
Error::DuplicateField("a"),
Error::Message("duplicate field `a`".to_owned()),
}
test_duplicate_field_enum<Enum> {
&[
@@ -916,22 +926,14 @@ declare_error_tests! {
Token::EnumMapSep,
Token::Str("a"),
],
Error::DuplicateField("a"),
Error::Message("duplicate field `a`".to_owned()),
}
test_enum_unit_usize<Enum> {
test_enum_out_of_range<Enum> {
&[
Token::EnumStart("Enum"),
Token::Usize(0),
Token::U32(4),
Token::Unit,
],
Error::InvalidType(Type::U64),
}
test_enum_unit_bytes<Enum> {
&[
Token::EnumStart("Enum"),
Token::Bytes(b"Unit"),
Token::Unit,
],
Error::InvalidType(Type::Bytes),
Error::Message("invalid value: integer `4`, expected variant index 0 <= i < 4".into()),
}
}
+6 -8
View File
@@ -60,14 +60,12 @@ declare_ser_tests! {
false => &[Token::Bool(false)],
}
test_isizes {
0isize => &[Token::Isize(0)],
0i8 => &[Token::I8(0)],
0i16 => &[Token::I16(0)],
0i32 => &[Token::I32(0)],
0i64 => &[Token::I64(0)],
}
test_usizes {
0usize => &[Token::Usize(0)],
0u8 => &[Token::U8(0)],
0u16 => &[Token::U16(0)],
0u32 => &[Token::U32(0)],
@@ -432,7 +430,7 @@ fn test_cannot_serialize_paths() {
assert_ser_tokens_error(
&Path::new(path),
&[],
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
Error::Message("path contains invalid UTF-8 characters".to_owned()));
let mut path_buf = PathBuf::new();
path_buf.push(path);
@@ -440,7 +438,7 @@ fn test_cannot_serialize_paths() {
assert_ser_tokens_error(
&path_buf,
&[],
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
Error::Message("path contains invalid UTF-8 characters".to_owned()));
}
#[test]
@@ -448,17 +446,17 @@ fn test_enum_skipped() {
assert_ser_tokens_error(
&Enum::SkippedUnit,
&[],
Error::InvalidValue("The enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
Error::Message("the enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
assert_ser_tokens_error(
&Enum::SkippedOne(42),
&[],
Error::InvalidValue("The enum variant Enum::SkippedOne cannot be serialized".to_owned()));
Error::Message("the enum variant Enum::SkippedOne cannot be serialized".to_owned()));
assert_ser_tokens_error(
&Enum::SkippedSeq(1, 2),
&[],
Error::InvalidValue("The enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
Error::Message("the enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
assert_ser_tokens_error(
&Enum::SkippedMap { _a: 1, _b: 2 },
&[],
Error::InvalidValue("The enum variant Enum::SkippedMap cannot be serialized".to_owned()));
Error::Message("the enum variant Enum::SkippedMap cannot be serialized".to_owned()));
}