mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 13:57:55 +00:00
Compare commits
169 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7612fd8e82 | |||
| 4c77af53e5 | |||
| 5d9c1aeb06 | |||
| 59e48997dd | |||
| ffcd97834f | |||
| e0c049dbf2 | |||
| 8cb6607e82 | |||
| 1ffb0570b6 | |||
| 2c1dd60575 | |||
| 24f849da2d | |||
| a5024a4238 | |||
| b105423e5e | |||
| 42c1bc2907 | |||
| c334c1c7b5 | |||
| 92668d7061 | |||
| b9d865d8e7 | |||
| fc4e370ba9 | |||
| a982d27536 | |||
| dc87826298 | |||
| a09a8a039a | |||
| ea702755a2 | |||
| d161911c63 | |||
| e27553d3df | |||
| 48eaf988bc | |||
| 73a364d4fd | |||
| 6dfdcb6ba1 | |||
| 089c7eb1d7 | |||
| 1e05fc2145 | |||
| 977612d8dd | |||
| 5855078703 | |||
| 3c88a93fb2 | |||
| 530c29466e | |||
| ea99e8b686 | |||
| 2a148112d4 | |||
| a4126e4c5a | |||
| d1325862f7 | |||
| 1f65ce75ec | |||
| 9536e52aa6 | |||
| be0c755731 | |||
| 42bc63bed8 | |||
| e41b940a3d | |||
| 88149fc0c3 | |||
| 5ecfb3b388 | |||
| 13a9f929de | |||
| e40fbe0767 | |||
| 0a10116bf5 | |||
| b1fbbfd3ce | |||
| 984ebcead0 | |||
| aa88f01cdc | |||
| 13794c1b48 | |||
| b5e64abba1 | |||
| 503ce310f5 | |||
| b26f291d93 | |||
| bc6bc9e3f0 | |||
| 3a52364f3e | |||
| 4d1627fc96 | |||
| 7c04bf36d9 | |||
| 4b06030666 | |||
| a5a04306f2 | |||
| f9885c4826 | |||
| 04f25eb122 | |||
| 2fea5f3e1c | |||
| 905b2c3cf3 | |||
| d5b428a087 | |||
| b3b8056d93 | |||
| 137cf9bab8 | |||
| 7372f152bd | |||
| a43da15b74 | |||
| 212cbbd8bf | |||
| 738aa31733 | |||
| 787ecc6a82 | |||
| 9fc8a86bcc | |||
| 800442a75e | |||
| 88debb3fb8 | |||
| 88a4ed9cd7 | |||
| bdba6fc5b0 | |||
| dec116311e | |||
| 8c49e6d6a5 | |||
| 7cc24a43fb | |||
| c008c6d3a8 | |||
| c9f5d08ed1 | |||
| fff6c9cb66 | |||
| cb5e7c6264 | |||
| 4ef1128546 | |||
| 227bea1d0b | |||
| 766ede965e | |||
| eb5a49e380 | |||
| 2df529cac5 | |||
| 4b66463011 | |||
| b907cfef85 | |||
| 506c8cc087 | |||
| 3951ef91c0 | |||
| b0d20afdfb | |||
| 5e6ee523d2 | |||
| a07b6bd9e7 | |||
| 8dd06eed2f | |||
| 5b668ed87a | |||
| abe305dbfe | |||
| 2d1a60c056 | |||
| 5edfdba940 | |||
| 756bff534f | |||
| 110d36fa14 | |||
| 8c576fe9fb | |||
| b860d3cb1f | |||
| dced4416a7 | |||
| ca47eb929c | |||
| b01c23b5ee | |||
| 3aaf29c846 | |||
| d2eea87001 | |||
| 8242c64152 | |||
| 9e45bd8c87 | |||
| 405b534254 | |||
| d34be74dfd | |||
| c475df8320 | |||
| 2b8a620807 | |||
| 1cd6aee562 | |||
| 90d4d7b37b | |||
| 1f8b803607 | |||
| 516cc8b04e | |||
| 0676477cd7 | |||
| 4193122472 | |||
| eb6fb1d40e | |||
| bf873a7b3f | |||
| fbd4a17467 | |||
| ad34c14c8c | |||
| e461a23798 | |||
| 894a21bc1f | |||
| 1ecf3730ee | |||
| 7a0e8f73b4 | |||
| b6e8b58cb2 | |||
| a3f556959f | |||
| 9338c4f1b9 | |||
| 28d67f4172 | |||
| 2401ae61a8 | |||
| 57d3fce0c6 | |||
| a020cceed8 | |||
| 49e985eb90 | |||
| 63def96c66 | |||
| 2fea8c9c28 | |||
| b7ea213926 | |||
| 871fb5adee | |||
| 2c984980a0 | |||
| 36f07912b8 | |||
| 7222cf7514 | |||
| 08c59a2e0e | |||
| 4a0bf4de65 | |||
| 95ffca9bbe | |||
| 5e47c87ba0 | |||
| c6d5d9be14 | |||
| d63d09f4db | |||
| de6d00c306 | |||
| 5bda95ba81 | |||
| 36641e7b81 | |||
| 6eca34c45c | |||
| 7efa0153b0 | |||
| 8dba87661b | |||
| 17fb4cb503 | |||
| 5bd0386b8e | |||
| 8b484c9703 | |||
| a16f07858b | |||
| 133d117bf4 | |||
| e7f3a80867 | |||
| f8c3d225a3 | |||
| 6d40d9e8ec | |||
| c91fca19e1 | |||
| f13a805530 | |||
| 54802983b8 | |||
| f430d9d1c8 | |||
| 85f1bf0259 |
+5
-5
@@ -1,8 +1,7 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
language: rust
|
language: rust
|
||||||
rust:
|
rust:
|
||||||
- 1.10.0
|
- 1.13.0
|
||||||
- 1.11.0
|
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
@@ -11,7 +10,7 @@ before_script:
|
|||||||
- export PATH=$HOME/.local/bin:$PATH
|
- export PATH=$HOME/.local/bin:$PATH
|
||||||
script:
|
script:
|
||||||
- (cd serde && travis-cargo build)
|
- (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 --only nightly test -- --features unstable-testing)
|
||||||
- (cd serde && travis-cargo build -- --no-default-features)
|
- (cd serde && travis-cargo build -- --no-default-features)
|
||||||
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
|
- (cd serde && travis-cargo --only nightly build -- --no-default-features --features alloc)
|
||||||
@@ -19,8 +18,9 @@ script:
|
|||||||
- (cd testing && travis-cargo --skip nightly test)
|
- (cd testing && travis-cargo --skip nightly test)
|
||||||
- (cd testing && travis-cargo --only nightly test -- --features unstable-testing)
|
- (cd testing && travis-cargo --only nightly test -- --features unstable-testing)
|
||||||
- (cd serde_derive && travis-cargo --only nightly test)
|
- (cd serde_derive && travis-cargo --only nightly test)
|
||||||
- (cd examples/serde-syntex-example && travis-cargo --skip nightly run)
|
- (cd serde_derive/no-std-tests && travis-cargo --only nightly build)
|
||||||
- (cd examples/serde-syntex-example && travis-cargo --only nightly run -- --no-default-features --features unstable)
|
#- (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)
|
- (cd serde && travis-cargo --only stable doc)
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
|||||||
@@ -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.
|
|
||||||
|
|
||||||
@@ -11,12 +11,11 @@ You may be looking for:
|
|||||||
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
||||||
- [Examples](https://serde.rs/examples.html)
|
- [Examples](https://serde.rs/examples.html)
|
||||||
- [API documentation](https://docs.serde.rs/serde/)
|
- [API documentation](https://docs.serde.rs/serde/)
|
||||||
|
- [Release notes](https://github.com/serde-rs/serde/releases)
|
||||||
|
|
||||||
## Serde in action
|
## Serde in action
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
@@ -50,8 +49,9 @@ fn main() {
|
|||||||
Serde developers live in the #serde channel on
|
Serde developers live in the #serde channel on
|
||||||
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
|
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
|
||||||
good resource with generally faster response time but less specific knowledge
|
good resource with generally faster response time but less specific knowledge
|
||||||
about Serde. If IRC is not your thing, we are happy to respond to [GitHub
|
about Serde. If IRC is not your thing or you don't get a good response, we are
|
||||||
issues](https://github.com/serde-rs/serde/issues/new) as well.
|
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
|
||||||
|
as well.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ name = "serde-syntex-example"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
publish = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["serde_codegen"]
|
default = ["serde_codegen"]
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![cfg_attr(feature = "serde_derive", feature(proc_macro))]
|
|
||||||
|
|
||||||
#[cfg(feature = "serde_derive")]
|
#[cfg(feature = "serde_derive")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|||||||
+9
-2
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.8.16"
|
version = "0.9.1"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -9,8 +9,12 @@ repository = "https://github.com/serde-rs/serde"
|
|||||||
documentation = "https://docs.serde.rs/serde/"
|
documentation = "https://docs.serde.rs/serde/"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
keywords = ["serde", "serialization"]
|
keywords = ["serde", "serialization"]
|
||||||
|
categories = ["encoding"]
|
||||||
include = ["Cargo.toml", "src/**/*.rs"]
|
include = ["Cargo.toml", "src/**/*.rs"]
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|
||||||
@@ -21,4 +25,7 @@ collections = ["alloc"]
|
|||||||
unstable-testing = ["clippy", "unstable", "std"]
|
unstable-testing = ["clippy", "unstable", "std"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "0.*", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_derive = "0.9"
|
||||||
|
|||||||
+86
-16
@@ -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::{ops, fmt, char, iter, slice};
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
@@ -6,14 +22,36 @@ use core::fmt::Write;
|
|||||||
use ser;
|
use ser;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[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")]
|
#[cfg(feature = "collections")]
|
||||||
use collections::Vec;
|
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)]
|
#[derive(Clone, Copy, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Bytes<'a> {
|
pub struct Bytes<'a> {
|
||||||
bytes: &'a [u8],
|
bytes: &'a [u8],
|
||||||
@@ -65,7 +103,7 @@ impl<'a> ops::Deref for Bytes<'a> {
|
|||||||
|
|
||||||
impl<'a> ser::Serialize for Bytes<'a> {
|
impl<'a> ser::Serialize for Bytes<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: ser::Serializer
|
where S: ser::Serializer
|
||||||
{
|
{
|
||||||
serializer.serialize_bytes(self.bytes)
|
serializer.serialize_bytes(self.bytes)
|
||||||
@@ -84,9 +122,27 @@ mod bytebuf {
|
|||||||
use de;
|
use de;
|
||||||
|
|
||||||
#[cfg(feature = "collections")]
|
#[cfg(feature = "collections")]
|
||||||
use collections::Vec;
|
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)]
|
#[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct ByteBuf {
|
pub struct ByteBuf {
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
@@ -168,7 +224,7 @@ mod bytebuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ser::Serialize for ByteBuf {
|
impl ser::Serialize for ByteBuf {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: ser::Serializer
|
where S: ser::Serializer
|
||||||
{
|
{
|
||||||
serializer.serialize_bytes(self)
|
serializer.serialize_bytes(self)
|
||||||
@@ -181,15 +237,19 @@ mod bytebuf {
|
|||||||
impl de::Visitor for ByteBufVisitor {
|
impl de::Visitor for ByteBufVisitor {
|
||||||
type Value = ByteBuf;
|
type Value = ByteBuf;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("byte array")
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
|
fn visit_unit<E>(self) -> Result<ByteBuf, E>
|
||||||
where E: de::Error,
|
where E: de::Error,
|
||||||
{
|
{
|
||||||
Ok(ByteBuf::new())
|
Ok(ByteBuf::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<ByteBuf, V::Error>
|
fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
|
||||||
where V: de::SeqVisitor,
|
where V: de::SeqVisitor,
|
||||||
{
|
{
|
||||||
let (len, _) = visitor.size_hint();
|
let (len, _) = visitor.size_hint();
|
||||||
@@ -199,20 +259,30 @@ mod bytebuf {
|
|||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
try!(visitor.end());
|
|
||||||
|
|
||||||
Ok(ByteBuf::from(values))
|
Ok(ByteBuf::from(values))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<ByteBuf, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
|
||||||
where E: de::Error,
|
where E: de::Error,
|
||||||
{
|
{
|
||||||
self.visit_byte_buf(v.to_vec())
|
Ok(ByteBuf::from(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
|
||||||
|
where E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(ByteBuf::from(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
|
||||||
|
where E: de::Error,
|
||||||
|
{
|
||||||
|
Ok(ByteBuf::from(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
|
||||||
where E: de::Error,
|
where E: de::Error,
|
||||||
{
|
{
|
||||||
Ok(ByteBuf::from(v))
|
Ok(ByteBuf::from(v))
|
||||||
@@ -221,10 +291,10 @@ mod bytebuf {
|
|||||||
|
|
||||||
impl de::Deserialize for ByteBuf {
|
impl de::Deserialize for ByteBuf {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<ByteBuf, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
|
||||||
where D: de::Deserializer
|
where D: de::Deserializer
|
||||||
{
|
{
|
||||||
deserializer.deserialize_bytes(ByteBufVisitor)
|
deserializer.deserialize_byte_buf(ByteBufVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+230
-215
File diff suppressed because it is too large
Load Diff
+1238
-465
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||||
|
}
|
||||||
+364
-425
File diff suppressed because it is too large
Load Diff
@@ -1,30 +1,7 @@
|
|||||||
//! A stand-in for `std::error`
|
//! A stand-in for `std::error`
|
||||||
use core::any::TypeId;
|
|
||||||
use core::fmt::{Debug, Display};
|
use core::fmt::{Debug, Display};
|
||||||
|
|
||||||
|
|
||||||
/// A stand-in for `std::error::Error`, which requires no allocation.
|
/// 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 {
|
pub trait Error: Debug + Display {
|
||||||
/// A short description of the error.
|
/// A short description of the error.
|
||||||
///
|
///
|
||||||
@@ -35,10 +12,4 @@ pub trait Error: Debug + Display {
|
|||||||
|
|
||||||
/// The lower-level cause of this error, if any.
|
/// The lower-level cause of this error, if any.
|
||||||
fn cause(&self) -> Option<&Error> { None }
|
fn cause(&self) -> Option<&Error> { None }
|
||||||
|
|
||||||
/// Stubbed! Returns type_id of `()`
|
|
||||||
#[doc(hidden)]
|
|
||||||
fn type_id(&self) -> TypeId where Self: 'static {
|
|
||||||
TypeId::of::<()>()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}")
|
||||||
|
}
|
||||||
+75
-26
@@ -1,49 +1,93 @@
|
|||||||
//! Serde Serialization Framework
|
//! # Serde
|
||||||
//!
|
//!
|
||||||
//! Serde is a powerful framework that enables serialization libraries to generically serialize
|
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
|
||||||
//! Rust data structures without the overhead of runtime type information. In many situations, the
|
//! structures efficiently and generically.
|
||||||
//! 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.
|
|
||||||
//!
|
//!
|
||||||
//! For a detailed tutorial on the different ways to use serde please check out the
|
//! The Serde ecosystem consists of data structures that know how to serialize
|
||||||
//! [github repository](https://github.com/serde-rs/serde)
|
//! 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")]
|
#![doc(html_root_url="https://docs.serde.rs")]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![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 = "alloc", feature(alloc))]
|
||||||
#![cfg_attr(feature = "collections", feature(collections, enumset))]
|
#![cfg_attr(feature = "collections", feature(collections, enumset))]
|
||||||
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||||
#![cfg_attr(feature = "clippy", allow(linkedlist))]
|
#![cfg_attr(feature = "clippy", allow(linkedlist, type_complexity))]
|
||||||
|
|
||||||
#![cfg_attr(any(not(feature = "std"), feature = "unstable"), allow(unused_variables, unused_imports, unused_features, dead_code))]
|
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
#[cfg(feature = "collections")]
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", feature = "alloc"))]
|
#[cfg(feature = "alloc")]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
extern crate core as actual_core;
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
mod core {
|
mod core {
|
||||||
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
|
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};
|
usize, f32, f64, char, str, num, slice, iter, cell, default, result};
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
extern crate core;
|
pub use actual_core::nonzero;
|
||||||
#[cfg(feature = "unstable")]
|
|
||||||
pub use self::core::nonzero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use ser::{Serialize, Serializer};
|
pub use ser::{Serialize, Serializer};
|
||||||
pub use de::{Deserialize, Deserializer, Error};
|
pub use de::{Deserialize, Deserializer};
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
macro_rules! format {
|
|
||||||
($s:expr, $($rest:tt)*) => ($s)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
@@ -51,8 +95,13 @@ mod macros;
|
|||||||
pub mod bytes;
|
pub mod bytes;
|
||||||
pub mod de;
|
pub mod de;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
#[doc(hidden)]
|
||||||
pub mod iter;
|
pub mod iter;
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg_attr(feature = "std", doc(hidden))]
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
// Generated code uses these to support no_std. Not public API.
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod export;
|
||||||
|
|||||||
+60
-49
@@ -4,7 +4,7 @@
|
|||||||
macro_rules! forward_to_deserialize_method {
|
macro_rules! forward_to_deserialize_method {
|
||||||
($func:ident($($arg:ty),*)) => {
|
($func:ident($($arg:ty),*)) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
|
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
|
||||||
where __V: $crate::de::Visitor
|
where __V: $crate::de::Visitor
|
||||||
{
|
{
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
@@ -18,7 +18,7 @@ macro_rules! forward_to_deserialize_method {
|
|||||||
macro_rules! forward_to_deserialize_method {
|
macro_rules! forward_to_deserialize_method {
|
||||||
($func:ident($($arg:ty),*)) => {
|
($func:ident($($arg:ty),*)) => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
|
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
|
||||||
where __V: $crate::de::Visitor
|
where __V: $crate::de::Visitor
|
||||||
{
|
{
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
@@ -26,43 +26,12 @@ macro_rules! forward_to_deserialize_method {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! forward_to_deserialize_enum {
|
|
||||||
() => {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::std::result::Result<__V::Value, Self::Error>
|
|
||||||
where __V: $crate::de::EnumVisitor
|
|
||||||
{
|
|
||||||
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! forward_to_deserialize_enum {
|
|
||||||
() => {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::core::result::Result<__V::Value, Self::Error>
|
|
||||||
where __V: $crate::de::EnumVisitor
|
|
||||||
{
|
|
||||||
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! forward_to_deserialize_helper {
|
macro_rules! forward_to_deserialize_helper {
|
||||||
(bool) => {
|
(bool) => {
|
||||||
forward_to_deserialize_method!{deserialize_bool()}
|
forward_to_deserialize_method!{deserialize_bool()}
|
||||||
};
|
};
|
||||||
(usize) => {
|
|
||||||
forward_to_deserialize_method!{deserialize_usize()}
|
|
||||||
};
|
|
||||||
(u8) => {
|
(u8) => {
|
||||||
forward_to_deserialize_method!{deserialize_u8()}
|
forward_to_deserialize_method!{deserialize_u8()}
|
||||||
};
|
};
|
||||||
@@ -75,9 +44,6 @@ macro_rules! forward_to_deserialize_helper {
|
|||||||
(u64) => {
|
(u64) => {
|
||||||
forward_to_deserialize_method!{deserialize_u64()}
|
forward_to_deserialize_method!{deserialize_u64()}
|
||||||
};
|
};
|
||||||
(isize) => {
|
|
||||||
forward_to_deserialize_method!{deserialize_isize()}
|
|
||||||
};
|
|
||||||
(i8) => {
|
(i8) => {
|
||||||
forward_to_deserialize_method!{deserialize_i8()}
|
forward_to_deserialize_method!{deserialize_i8()}
|
||||||
};
|
};
|
||||||
@@ -120,6 +86,9 @@ macro_rules! forward_to_deserialize_helper {
|
|||||||
(bytes) => {
|
(bytes) => {
|
||||||
forward_to_deserialize_method!{deserialize_bytes()}
|
forward_to_deserialize_method!{deserialize_bytes()}
|
||||||
};
|
};
|
||||||
|
(byte_buf) => {
|
||||||
|
forward_to_deserialize_method!{deserialize_byte_buf()}
|
||||||
|
};
|
||||||
(map) => {
|
(map) => {
|
||||||
forward_to_deserialize_method!{deserialize_map()}
|
forward_to_deserialize_method!{deserialize_map()}
|
||||||
};
|
};
|
||||||
@@ -141,36 +110,78 @@ macro_rules! forward_to_deserialize_helper {
|
|||||||
(tuple) => {
|
(tuple) => {
|
||||||
forward_to_deserialize_method!{deserialize_tuple(usize)}
|
forward_to_deserialize_method!{deserialize_tuple(usize)}
|
||||||
};
|
};
|
||||||
|
(enum) => {
|
||||||
|
forward_to_deserialize_method!{deserialize_enum(&'static str, &'static [&'static str])}
|
||||||
|
};
|
||||||
(ignored_any) => {
|
(ignored_any) => {
|
||||||
forward_to_deserialize_method!{deserialize_ignored_any()}
|
forward_to_deserialize_method!{deserialize_ignored_any()}
|
||||||
};
|
};
|
||||||
(enum) => {
|
|
||||||
forward_to_deserialize_enum!();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to forward `Deserializer` methods to `Deserializer::deserialize`.
|
// Super explicit first paragraph because this shows up at the top level and
|
||||||
/// Every given method ignores all arguments and forwards to `deserialize`.
|
// trips up people who are just looking for basic Serialize / Deserialize
|
||||||
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`; a
|
// documentation.
|
||||||
/// better approach is tracked in [serde-rs/serde#521][1].
|
//
|
||||||
|
/// 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 {
|
/// impl Deserializer for MyDeserializer {
|
||||||
/// fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
/// # type Error = value::Error;
|
||||||
|
/// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
/// where V: Visitor
|
/// where V: Visitor
|
||||||
/// {
|
/// {
|
||||||
/// /* ... */
|
/// /* ... */
|
||||||
|
/// # let _ = visitor;
|
||||||
|
/// # unimplemented!()
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// forward_to_deserialize! {
|
/// forward_to_deserialize! {
|
||||||
/// bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
|
/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
|
||||||
/// unit option seq seq_fixed_size bytes map unit_struct newtype_struct
|
/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
|
||||||
/// tuple_struct struct struct_field tuple enum ignored_any
|
/// tuple_struct struct struct_field tuple enum ignored_any
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
|
/// # fn main() {}
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
/// [1]: https://github.com/serde-rs/serde/issues/521
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! forward_to_deserialize {
|
macro_rules! forward_to_deserialize {
|
||||||
($($func:ident)*) => {
|
($($func:ident)*) => {
|
||||||
|
|||||||
+147
-80
@@ -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")]
|
#[cfg(feature = "std")]
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
#[cfg(all(feature = "collections", not(feature = "std")))]
|
#[cfg(all(feature = "collections", not(feature = "std")))]
|
||||||
@@ -30,19 +24,18 @@ use collections::{
|
|||||||
Vec,
|
Vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
#[cfg(feature = "collections")]
|
||||||
use collections::enum_set::{CLike, EnumSet};
|
use collections::enum_set::{CLike, EnumSet};
|
||||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
#[cfg(feature = "collections")]
|
||||||
use collections::borrow::ToOwned;
|
use collections::borrow::ToOwned;
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
use core::hash::{Hash, BuildHasher};
|
use core::hash::{Hash, BuildHasher};
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
use core::iter;
|
use core::iter;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::net;
|
use std::net;
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
use core::num;
|
|
||||||
#[cfg(feature = "unstable")]
|
|
||||||
use core::ops;
|
use core::ops;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::path;
|
use std::path;
|
||||||
@@ -67,33 +60,39 @@ use core::marker::PhantomData;
|
|||||||
use core::nonzero::{NonZero, Zeroable};
|
use core::nonzero::{NonZero, Zeroable};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Error,
|
|
||||||
Serialize,
|
Serialize,
|
||||||
|
SerializeSeq,
|
||||||
|
SerializeTuple,
|
||||||
Serializer,
|
Serializer,
|
||||||
};
|
};
|
||||||
|
#[cfg(any(feature = "std", feature = "unstable"))]
|
||||||
|
use super::Error;
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
use super::Iterator;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! impl_visit {
|
macro_rules! impl_visit {
|
||||||
($ty:ty, $method:ident) => {
|
($ty:ty, $method:ident $($cast:tt)*) => {
|
||||||
impl Serialize for $ty {
|
impl Serialize for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.$method(*self)
|
serializer.$method(*self $($cast)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_visit!(bool, serialize_bool);
|
impl_visit!(bool, serialize_bool);
|
||||||
impl_visit!(isize, serialize_isize);
|
impl_visit!(isize, serialize_i64 as i64);
|
||||||
impl_visit!(i8, serialize_i8);
|
impl_visit!(i8, serialize_i8);
|
||||||
impl_visit!(i16, serialize_i16);
|
impl_visit!(i16, serialize_i16);
|
||||||
impl_visit!(i32, serialize_i32);
|
impl_visit!(i32, serialize_i32);
|
||||||
impl_visit!(i64, serialize_i64);
|
impl_visit!(i64, serialize_i64);
|
||||||
impl_visit!(usize, serialize_usize);
|
impl_visit!(usize, serialize_u64 as u64);
|
||||||
impl_visit!(u8, serialize_u8);
|
impl_visit!(u8, serialize_u8);
|
||||||
impl_visit!(u16, serialize_u16);
|
impl_visit!(u16, serialize_u16);
|
||||||
impl_visit!(u32, serialize_u32);
|
impl_visit!(u32, serialize_u32);
|
||||||
@@ -106,7 +105,7 @@ impl_visit!(char, serialize_char);
|
|||||||
|
|
||||||
impl Serialize for str {
|
impl Serialize for str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(self)
|
serializer.serialize_str(self)
|
||||||
@@ -116,7 +115,7 @@ impl Serialize for str {
|
|||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[cfg(any(feature = "std", feature = "collections"))]
|
||||||
impl Serialize for String {
|
impl Serialize for String {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(&self[..]).serialize(serializer)
|
(&self[..]).serialize(serializer)
|
||||||
@@ -125,9 +124,11 @@ impl Serialize for String {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<T> Serialize for Option<T> where T: Serialize {
|
impl<T> Serialize for Option<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
@@ -141,7 +142,7 @@ impl<T> Serialize for Option<T> where T: Serialize {
|
|||||||
|
|
||||||
impl<T> Serialize for PhantomData<T> {
|
impl<T> Serialize for PhantomData<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_unit_struct("PhantomData")
|
serializer.serialize_unit_struct("PhantomData")
|
||||||
@@ -155,14 +156,14 @@ impl<T> Serialize for [T]
|
|||||||
where T: Serialize,
|
where T: Serialize,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let mut state = try!(serializer.serialize_seq(Some(self.len())));
|
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
|
||||||
for e in self {
|
for e in self {
|
||||||
try!(serializer.serialize_seq_elt(&mut state, e));
|
try!(seq.serialize_element(e));
|
||||||
}
|
}
|
||||||
serializer.serialize_seq_end(state)
|
seq.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,14 +173,14 @@ macro_rules! array_impls {
|
|||||||
($len:expr) => {
|
($len:expr) => {
|
||||||
impl<T> Serialize for [T; $len] where T: Serialize {
|
impl<T> Serialize for [T; $len] where T: Serialize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let mut state = try!(serializer.serialize_seq_fixed_size($len));
|
let mut seq = try!(serializer.serialize_seq_fixed_size($len));
|
||||||
for e in self {
|
for e in self {
|
||||||
try!(serializer.serialize_seq_elt(&mut state, e));
|
try!(seq.serialize_element(e));
|
||||||
}
|
}
|
||||||
serializer.serialize_seq_end(state)
|
seq.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,17 +222,44 @@ array_impls!(32);
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
impl<'a, I> Serialize for Iterator<I>
|
||||||
|
where I: IntoIterator, <I as IntoIterator>::Item: Serialize
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer,
|
||||||
|
{
|
||||||
|
// 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(Error::custom("Iterator used twice")),
|
||||||
|
};
|
||||||
|
let size = match iter.size_hint() {
|
||||||
|
(lo, Some(hi)) if lo == hi => Some(lo),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let mut seq = try!(serializer.serialize_seq(size));
|
||||||
|
for e in iter {
|
||||||
|
try!(seq.serialize_element(&e));
|
||||||
|
}
|
||||||
|
seq.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! serialize_seq {
|
macro_rules! serialize_seq {
|
||||||
() => {
|
() => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let mut state = try!(serializer.serialize_seq(Some(self.len())));
|
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
|
||||||
for e in self {
|
for e in self {
|
||||||
try!(serializer.serialize_seq_elt(&mut state, e));
|
try!(seq.serialize_element(&e));
|
||||||
}
|
}
|
||||||
serializer.serialize_seq_end(state)
|
seq.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,7 +278,7 @@ impl<T> Serialize for BTreeSet<T>
|
|||||||
serialize_seq!();
|
serialize_seq!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", feature = "collections"))]
|
#[cfg(feature = "collections")]
|
||||||
impl<T> Serialize for EnumSet<T>
|
impl<T> Serialize for EnumSet<T>
|
||||||
where T: Serialize + CLike
|
where T: Serialize + CLike
|
||||||
{
|
{
|
||||||
@@ -273,30 +301,50 @@ impl<T> Serialize for LinkedList<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[cfg(any(feature = "std", feature = "collections"))]
|
||||||
impl<T> Serialize for Vec<T> where T: Serialize {
|
impl<T> Serialize for Vec<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
serialize_seq!();
|
serialize_seq!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[cfg(any(feature = "std", feature = "collections"))]
|
||||||
impl<T> Serialize for VecDeque<T> where T: Serialize {
|
impl<T> Serialize for VecDeque<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
serialize_seq!();
|
serialize_seq!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
impl<A> Serialize for ops::Range<A>
|
impl<A> Serialize for ops::Range<A>
|
||||||
where A: Serialize + Clone + iter::Step + num::One,
|
where ops::Range<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
|
||||||
for<'a> &'a A: ops::Add<&'a A, Output = A>,
|
A: Serialize,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let len = iter::Step::steps_between(&self.start, &self.end, &A::one());
|
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
|
||||||
let mut state = try!(serializer.serialize_seq(len));
|
|
||||||
for e in self.clone() {
|
for e in self.clone() {
|
||||||
try!(serializer.serialize_seq_elt(&mut state, e));
|
try!(seq.serialize_element(&e));
|
||||||
}
|
}
|
||||||
serializer.serialize_seq_end(state)
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,7 +352,7 @@ impl<A> Serialize for ops::Range<A>
|
|||||||
|
|
||||||
impl Serialize for () {
|
impl Serialize for () {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_unit()
|
serializer.serialize_unit()
|
||||||
@@ -324,14 +372,14 @@ macro_rules! tuple_impls {
|
|||||||
where $($T: Serialize),+
|
where $($T: Serialize),+
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let mut state = try!(serializer.serialize_tuple($len));
|
let mut tuple = try!(serializer.serialize_tuple($len));
|
||||||
$(
|
$(
|
||||||
try!(serializer.serialize_tuple_elt(&mut state, &self.$idx));
|
try!(tuple.serialize_element(&self.$idx));
|
||||||
)+
|
)+
|
||||||
serializer.serialize_tuple_end(state)
|
tuple.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@@ -514,15 +562,16 @@ tuple_impls! {
|
|||||||
macro_rules! serialize_map {
|
macro_rules! serialize_map {
|
||||||
() => {
|
() => {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
let mut state = try!(serializer.serialize_map(Some(self.len())));
|
use super::SerializeMap;
|
||||||
|
let mut map = try!(serializer.serialize_map(Some(self.len())));
|
||||||
for (k, v) in self {
|
for (k, v) in self {
|
||||||
try!(serializer.serialize_map_key(&mut state, k));
|
try!(map.serialize_key(k));
|
||||||
try!(serializer.serialize_map_value(&mut state, v));
|
try!(map.serialize_value(v));
|
||||||
}
|
}
|
||||||
serializer.serialize_map_end(state)
|
map.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -548,7 +597,7 @@ impl<K, V, H> Serialize for HashMap<K, V, H>
|
|||||||
|
|
||||||
impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
|
impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -557,7 +606,7 @@ impl<'a, T: ?Sized> Serialize for &'a T where T: Serialize {
|
|||||||
|
|
||||||
impl<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize {
|
impl<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -565,9 +614,11 @@ impl<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T: ?Sized> Serialize for Box<T> where T: Serialize {
|
impl<T: ?Sized> Serialize for Box<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -575,9 +626,11 @@ impl<T: ?Sized> Serialize for Box<T> where T: Serialize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T> Serialize for Rc<T> where T: Serialize, {
|
impl<T> Serialize for Rc<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -585,9 +638,11 @@ impl<T> Serialize for Rc<T> where T: Serialize, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<T> Serialize for Arc<T> where T: Serialize, {
|
impl<T> Serialize for Arc<T>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -595,9 +650,11 @@ impl<T> Serialize for Arc<T> where T: Serialize, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "collections"))]
|
#[cfg(any(feature = "std", feature = "collections"))]
|
||||||
impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
|
impl<'a, T: ?Sized> Serialize for Cow<'a, T>
|
||||||
|
where T: Serialize + ToOwned
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
@@ -606,8 +663,13 @@ impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
|
impl<T, E> Serialize for Result<T, E>
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
where T: Serialize,
|
||||||
|
E: Serialize
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
match *self {
|
match *self {
|
||||||
Result::Ok(ref value) => {
|
Result::Ok(ref value) => {
|
||||||
serializer.serialize_newtype_variant("Result", 0, "Ok", value)
|
serializer.serialize_newtype_variant("Result", 0, "Ok", value)
|
||||||
@@ -623,13 +685,14 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for Duration {
|
impl Serialize for Duration {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("Duration", 2));
|
let mut state = try!(serializer.serialize_struct("Duration", 2));
|
||||||
try!(serializer.serialize_struct_elt(&mut state, "secs", self.as_secs()));
|
try!(state.serialize_field("secs", &self.as_secs()));
|
||||||
try!(serializer.serialize_struct_elt(&mut state, "nanos", self.subsec_nanos()));
|
try!(state.serialize_field("nanos", &self.subsec_nanos()));
|
||||||
serializer.serialize_struct_end(state)
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +700,7 @@ impl Serialize for Duration {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::IpAddr {
|
impl Serialize for net::IpAddr {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.to_string().serialize(serializer)
|
self.to_string().serialize(serializer)
|
||||||
@@ -646,7 +709,7 @@ impl Serialize for net::IpAddr {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::Ipv4Addr {
|
impl Serialize for net::Ipv4Addr {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.to_string().serialize(serializer)
|
self.to_string().serialize(serializer)
|
||||||
@@ -655,7 +718,7 @@ impl Serialize for net::Ipv4Addr {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::Ipv6Addr {
|
impl Serialize for net::Ipv6Addr {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.to_string().serialize(serializer)
|
self.to_string().serialize(serializer)
|
||||||
@@ -666,7 +729,7 @@ impl Serialize for net::Ipv6Addr {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::SocketAddr {
|
impl Serialize for net::SocketAddr {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
match *self {
|
match *self {
|
||||||
@@ -678,7 +741,7 @@ impl Serialize for net::SocketAddr {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::SocketAddrV4 {
|
impl Serialize for net::SocketAddrV4 {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.to_string().serialize(serializer)
|
self.to_string().serialize(serializer)
|
||||||
@@ -687,7 +750,7 @@ impl Serialize for net::SocketAddrV4 {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for net::SocketAddrV6 {
|
impl Serialize for net::SocketAddrV6 {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.to_string().serialize(serializer)
|
self.to_string().serialize(serializer)
|
||||||
@@ -698,19 +761,19 @@ impl Serialize for net::SocketAddrV6 {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for path::Path {
|
impl Serialize for path::Path {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
match self.to_str() {
|
match self.to_str() {
|
||||||
Some(s) => s.serialize(serializer),
|
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")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Serialize for path::PathBuf {
|
impl Serialize for path::PathBuf {
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer,
|
where S: Serializer,
|
||||||
{
|
{
|
||||||
self.as_path().serialize(serializer)
|
self.as_path().serialize(serializer)
|
||||||
@@ -718,8 +781,12 @@ impl Serialize for path::PathBuf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
impl<T> Serialize for NonZero<T> where T: Serialize + Zeroable {
|
impl<T> Serialize for NonZero<T>
|
||||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
where T: Serialize + Zeroable
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
(**self).serialize(serializer)
|
(**self).serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+700
-315
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen"
|
name = "serde_codegen"
|
||||||
version = "0.8.16"
|
version = "0.9.0"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
@@ -21,10 +21,12 @@ with-syntex = [
|
|||||||
with-syn = []
|
with-syn = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "0.*", optional = true }
|
||||||
post-expansion = "0.1.0"
|
quote = "0.3.8"
|
||||||
quote = "0.3"
|
serde_codegen_internals = { version = "=0.11.3", default-features = false, path = "../serde_codegen_internals" }
|
||||||
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
|
syn = { version = "0.10", features = ["aster", "visit"] }
|
||||||
syn = { version = "0.9", features = ["aster", "visit"] }
|
syntex = { version = "0.54", optional = true }
|
||||||
syntex = { version = "^0.46.0", optional = true }
|
syntex_syntax = { version = "0.54", optional = true }
|
||||||
syntex_syntax = { version = "^0.46.0", optional = true }
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
|
|||||||
+245
-234
@@ -1,4 +1,4 @@
|
|||||||
use syn::{self, aster};
|
use syn::{self, aster, Ident};
|
||||||
use quote::{self, Tokens};
|
use quote::{self, Tokens};
|
||||||
|
|
||||||
use bound;
|
use bound;
|
||||||
@@ -28,16 +28,16 @@ pub fn expand_derive_deserialize(item: &syn::MacroInput) -> Result<Tokens, Strin
|
|||||||
|
|
||||||
let where_clause = &impl_generics.where_clause;
|
let where_clause = &impl_generics.where_clause;
|
||||||
|
|
||||||
let dummy_const = aster::id(format!("_IMPL_DESERIALIZE_FOR_{}", item.ident));
|
let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", item.ident));
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
const #dummy_const: () = {
|
const #dummy_const: () = {
|
||||||
extern crate serde as _serde;
|
extern crate serde as _serde;
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics _serde::de::Deserialize for #ty #where_clause {
|
impl #impl_generics _serde::Deserialize for #ty #where_clause {
|
||||||
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<#ty, __D::Error>
|
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<#ty, __D::Error>
|
||||||
where __D: _serde::de::Deserializer
|
where __D: _serde::Deserializer
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -61,7 +61,7 @@ fn build_impl_generics(item: &Item) -> syn::Generics {
|
|||||||
None => {
|
None => {
|
||||||
let generics = bound::with_bound(item, &generics,
|
let generics = bound::with_bound(item, &generics,
|
||||||
needs_deserialize_bound,
|
needs_deserialize_bound,
|
||||||
&aster::path().ids(&["_serde", "de", "Deserialize"]).build());
|
&aster::path().ids(&["_serde", "Deserialize"]).build());
|
||||||
bound::with_bound(item, &generics,
|
bound::with_bound(item, &generics,
|
||||||
requires_default,
|
requires_default,
|
||||||
&aster::path().global().ids(&["std", "default", "Default"]).build())
|
&aster::path().global().ids(&["std", "default", "Default"]).build())
|
||||||
@@ -158,11 +158,11 @@ fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) {
|
|||||||
let phantom_types = generics.lifetimes.iter()
|
let phantom_types = generics.lifetimes.iter()
|
||||||
.map(|lifetime_def| {
|
.map(|lifetime_def| {
|
||||||
let lifetime = &lifetime_def.lifetime;
|
let lifetime = &lifetime_def.lifetime;
|
||||||
quote!(::std::marker::PhantomData<& #lifetime ()>)
|
quote!(_serde::export::PhantomData<& #lifetime ()>)
|
||||||
}).chain(generics.ty_params.iter()
|
}).chain(generics.ty_params.iter()
|
||||||
.map(|ty_param| {
|
.map(|ty_param| {
|
||||||
let ident = &ty_param.ident;
|
let ident = &ty_param.ident;
|
||||||
quote!(::std::marker::PhantomData<#ident>)
|
quote!(_serde::export::PhantomData<#ident>)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let all_params = generics.lifetimes.iter()
|
let all_params = generics.lifetimes.iter()
|
||||||
@@ -175,20 +175,14 @@ fn deserialize_visitor(generics: &syn::Generics) -> (Tokens, Tokens, Tokens) {
|
|||||||
quote!(#ident)
|
quote!(#ident)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let ty_param_idents: Vec<_> = generics.ty_params.iter()
|
let ty_param_idents = if generics.ty_params.is_empty() {
|
||||||
.map(|t| {
|
|
||||||
let ident = &t.ident;
|
|
||||||
quote!(#ident)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let ty_param_idents = if ty_param_idents.is_empty() {
|
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
let ty_param_idents = generics.ty_params.iter().map(|t| &t.ident);
|
||||||
Some(quote!(::<#(#ty_param_idents),*>))
|
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! {
|
quote! {
|
||||||
@@ -206,25 +200,30 @@ fn deserialize_unit_struct(
|
|||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
let type_name = item_attrs.name().deserialize_name();
|
let type_name = item_attrs.name().deserialize_name();
|
||||||
|
|
||||||
|
let expecting = format!("unit struct {}", type_ident);
|
||||||
|
|
||||||
quote!({
|
quote!({
|
||||||
struct __Visitor;
|
struct __Visitor;
|
||||||
|
|
||||||
impl _serde::de::Visitor for __Visitor {
|
impl _serde::de::Visitor for __Visitor {
|
||||||
type Value = #type_ident;
|
type Value = #type_ident;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
|
||||||
|
formatter.write_str(#expecting)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_unit<__E>(&mut self) -> ::std::result::Result<#type_ident, __E>
|
fn visit_unit<__E>(self) -> _serde::export::Result<#type_ident, __E>
|
||||||
where __E: _serde::de::Error,
|
where __E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
Ok(#type_ident)
|
Ok(#type_ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<__V>(&mut self, mut visitor: __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,
|
where __V: _serde::de::SeqVisitor,
|
||||||
{
|
{
|
||||||
try!(visitor.end());
|
Ok(#type_ident)
|
||||||
self.visit_unit()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +248,10 @@ fn deserialize_tuple(
|
|||||||
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
||||||
None => quote!(#type_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();
|
let nfields = fields.len();
|
||||||
|
|
||||||
@@ -272,7 +275,7 @@ fn deserialize_tuple(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let dispatch = if is_enum {
|
let dispatch = if is_enum {
|
||||||
quote!(visitor.visit_tuple(#nfields, #visitor_expr))
|
quote!(_serde::de::VariantVisitor::visit_tuple(visitor, #nfields, #visitor_expr))
|
||||||
} else if nfields == 1 {
|
} else if nfields == 1 {
|
||||||
let type_name = item_attrs.name().deserialize_name();
|
let type_name = item_attrs.name().deserialize_name();
|
||||||
quote!(deserializer.deserialize_newtype_struct(#type_name, #visitor_expr))
|
quote!(deserializer.deserialize_newtype_struct(#type_name, #visitor_expr))
|
||||||
@@ -281,16 +284,27 @@ fn deserialize_tuple(
|
|||||||
quote!(deserializer.deserialize_tuple_struct(#type_name, #nfields, #visitor_expr))
|
quote!(deserializer.deserialize_tuple_struct(#type_name, #nfields, #visitor_expr))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
|
let visitor_var = if all_skipped {
|
||||||
|
quote!(_)
|
||||||
|
} else {
|
||||||
|
quote!(mut visitor)
|
||||||
|
};
|
||||||
|
|
||||||
quote!({
|
quote!({
|
||||||
#visitor_item
|
#visitor_item
|
||||||
|
|
||||||
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||||
type Value = #ty;
|
type Value = #ty;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
|
||||||
|
formatter.write_str(#expecting)
|
||||||
|
}
|
||||||
|
|
||||||
#visit_newtype_struct
|
#visit_newtype_struct
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<__V>(&mut self, mut visitor: __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
|
where __V: _serde::de::SeqVisitor
|
||||||
{
|
{
|
||||||
#visit_seq
|
#visit_seq
|
||||||
@@ -308,15 +322,20 @@ fn deserialize_seq(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
is_struct: bool,
|
is_struct: bool,
|
||||||
) -> Tokens {
|
) -> 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 mut index_in_seq = 0usize;
|
||||||
let let_values: Vec<_> = fields.iter()
|
let let_values = vars.clone().zip(fields)
|
||||||
.enumerate()
|
.map(|(var, field)| {
|
||||||
.map(|(i, field)| {
|
|
||||||
let name = aster::id(format!("__field{}", i));
|
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let default = expr_is_missing(&field.attrs);
|
let default = expr_is_missing(&field.attrs);
|
||||||
quote! {
|
quote! {
|
||||||
let #name = #default;
|
let #var = #default;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let visit = match field.attrs.deserialize_with() {
|
let visit = match field.attrs.deserialize_with() {
|
||||||
@@ -335,43 +354,31 @@ fn deserialize_seq(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let assign = quote! {
|
let assign = quote! {
|
||||||
let #name = match #visit {
|
let #var = match #visit {
|
||||||
Some(value) => { value },
|
Some(value) => { value },
|
||||||
None => {
|
None => {
|
||||||
try!(visitor.end());
|
return Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
|
||||||
return Err(_serde::de::Error::invalid_length(#index_in_seq));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
index_in_seq += 1;
|
index_in_seq += 1;
|
||||||
assign
|
assign
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect();
|
|
||||||
|
|
||||||
let result = if is_struct {
|
let result = if is_struct {
|
||||||
let args = fields.iter()
|
let names = fields.iter().map(|f| &f.ident);
|
||||||
.enumerate()
|
|
||||||
.map(|(i, field)| {
|
|
||||||
let ident = field.ident.clone().expect("struct contains unnamed fields");
|
|
||||||
let value = aster::id(format!("__field{}", i));
|
|
||||||
quote!(#ident: #value)
|
|
||||||
});
|
|
||||||
quote! {
|
quote! {
|
||||||
#type_path { #(#args),* }
|
#type_path { #( #names: #vars ),* }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let args = (0..fields.len()).map(|i| aster::id(format!("__field{}", i)));
|
|
||||||
quote! {
|
quote! {
|
||||||
#type_path ( #(#args),* )
|
#type_path ( #(#vars),* )
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#(#let_values)*
|
#(#let_values)*
|
||||||
|
|
||||||
try!(visitor.end());
|
|
||||||
|
|
||||||
Ok(#result)
|
Ok(#result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,8 +408,8 @@ fn deserialize_newtype_struct(
|
|||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_newtype_struct<__E>(&mut self, __e: &mut __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::de::Deserializer,
|
where __E: _serde::Deserializer,
|
||||||
{
|
{
|
||||||
Ok(#type_path(#value))
|
Ok(#type_path(#value))
|
||||||
}
|
}
|
||||||
@@ -425,6 +432,10 @@ fn deserialize_struct(
|
|||||||
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
Some(variant_ident) => quote!(#type_ident::#variant_ident),
|
||||||
None => quote!(#type_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(
|
let visit_seq = deserialize_seq(
|
||||||
type_ident,
|
type_ident,
|
||||||
@@ -445,7 +456,7 @@ fn deserialize_struct(
|
|||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
let dispatch = if is_enum {
|
let dispatch = if is_enum {
|
||||||
quote! {
|
quote! {
|
||||||
visitor.visit_struct(FIELDS, #visitor_expr)
|
_serde::de::VariantVisitor::visit_struct(visitor, FIELDS, #visitor_expr)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let type_name = item_attrs.name().deserialize_name();
|
let type_name = item_attrs.name().deserialize_name();
|
||||||
@@ -454,6 +465,13 @@ fn deserialize_struct(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
|
let visitor_var = if all_skipped {
|
||||||
|
quote!(_)
|
||||||
|
} else {
|
||||||
|
quote!(mut visitor)
|
||||||
|
};
|
||||||
|
|
||||||
quote!({
|
quote!({
|
||||||
#field_visitor
|
#field_visitor
|
||||||
|
|
||||||
@@ -462,15 +480,19 @@ fn deserialize_struct(
|
|||||||
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||||
type Value = #ty;
|
type Value = #ty;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
|
||||||
|
formatter.write_str(#expecting)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<__V>(&mut self, mut visitor: __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
|
where __V: _serde::de::SeqVisitor
|
||||||
{
|
{
|
||||||
#visit_seq
|
#visit_seq
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_map<__V>(&mut 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
|
where __V: _serde::de::MapVisitor
|
||||||
{
|
{
|
||||||
#visit_map
|
#visit_map
|
||||||
@@ -494,48 +516,64 @@ fn deserialize_item_enum(
|
|||||||
|
|
||||||
let type_name = item_attrs.name().deserialize_name();
|
let type_name = item_attrs.name().deserialize_name();
|
||||||
|
|
||||||
|
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(
|
let variant_visitor = deserialize_field_visitor(
|
||||||
variants.iter()
|
variant_names_idents,
|
||||||
.map(|variant| variant.attrs.name().deserialize_name())
|
|
||||||
.collect(),
|
|
||||||
item_attrs,
|
item_attrs,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
let variant_names = variants.iter().map(|variant| variant.ident.to_string());
|
|
||||||
|
|
||||||
let variants_stmt = quote! {
|
|
||||||
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
|
||||||
};
|
|
||||||
|
|
||||||
let ignored_arm = if item_attrs.deny_unknown_fields() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(quote! {
|
|
||||||
__Field::__ignore => { Err(_serde::de::Error::end_of_stream()) }
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let mut variant_arms = vec![];
|
let variant_arms = variants.iter()
|
||||||
for (i, variant) in variants.iter().enumerate() {
|
.enumerate()
|
||||||
let variant_name = aster::id(format!("__field{}", i));
|
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||||
let variant_name = quote!(__Field::#variant_name);
|
.map(|(i, variant)| {
|
||||||
|
let variant_name = field_i(i);
|
||||||
|
|
||||||
let block = deserialize_variant(
|
let block = deserialize_variant(
|
||||||
type_ident,
|
type_ident,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
variant,
|
variant,
|
||||||
item_attrs,
|
item_attrs,
|
||||||
);
|
);
|
||||||
|
|
||||||
let arm = quote! {
|
quote! {
|
||||||
#variant_name => #block
|
(__Field::#variant_name, visitor) => #block
|
||||||
};
|
}
|
||||||
variant_arms.push(arm);
|
});
|
||||||
}
|
|
||||||
variant_arms.extend(ignored_arm.into_iter());
|
let all_skipped = variants.iter().all(|variant| variant.attrs.skip_deserializing());
|
||||||
|
let match_variant = if all_skipped {
|
||||||
|
// This is an empty enum like `enum Impossible {}` or an enum in which
|
||||||
|
// all variants have `#[serde(skip_deserializing)]`.
|
||||||
|
quote! {
|
||||||
|
// FIXME: Once we drop support for Rust 1.15:
|
||||||
|
// let Err(err) = visitor.visit_variant::<__Field>();
|
||||||
|
// Err(err)
|
||||||
|
visitor.visit_variant::<__Field>().map(|(impossible, _)| match impossible {})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
match try!(visitor.visit_variant()) {
|
||||||
|
#(#variant_arms)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics);
|
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics);
|
||||||
|
|
||||||
@@ -544,15 +582,17 @@ fn deserialize_item_enum(
|
|||||||
|
|
||||||
#visitor_item
|
#visitor_item
|
||||||
|
|
||||||
impl #impl_generics _serde::de::EnumVisitor for #visitor_ty #where_clause {
|
impl #impl_generics _serde::de::Visitor for #visitor_ty #where_clause {
|
||||||
type Value = #ty;
|
type Value = #ty;
|
||||||
|
|
||||||
fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<#ty, __V::Error>
|
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
|
||||||
where __V: _serde::de::VariantVisitor,
|
formatter.write_str(#expecting)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_enum<__V>(self, visitor: __V) -> _serde::export::Result<#ty, __V::Error>
|
||||||
|
where __V: _serde::de::EnumVisitor,
|
||||||
{
|
{
|
||||||
match try!(visitor.visit_variant()) {
|
#match_variant
|
||||||
#(#variant_arms)*
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +614,7 @@ fn deserialize_variant(
|
|||||||
match variant.style {
|
match variant.style {
|
||||||
Style::Unit => {
|
Style::Unit => {
|
||||||
quote!({
|
quote!({
|
||||||
try!(visitor.visit_unit());
|
try!(_serde::de::VariantVisitor::visit_unit(visitor));
|
||||||
Ok(#type_ident::#variant_ident)
|
Ok(#type_ident::#variant_ident)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -618,7 +658,9 @@ fn deserialize_newtype_variant(
|
|||||||
let visit = match field.attrs.deserialize_with() {
|
let visit = match field.attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
let field_ty = &field.ty;
|
let field_ty = &field.ty;
|
||||||
quote!(try!(visitor.visit_newtype::<#field_ty>()))
|
quote! {
|
||||||
|
try!(_serde::de::VariantVisitor::visit_newtype::<#field_ty>(visitor))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with(
|
let (wrapper, wrapper_impl, wrapper_ty) = wrap_deserialize_with(
|
||||||
@@ -626,7 +668,7 @@ fn deserialize_newtype_variant(
|
|||||||
quote!({
|
quote!({
|
||||||
#wrapper
|
#wrapper
|
||||||
#wrapper_impl
|
#wrapper_impl
|
||||||
try!(visitor.visit_newtype::<#wrapper_ty>()).value
|
try!(_serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(visitor)).value
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -636,105 +678,63 @@ fn deserialize_newtype_variant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_field_visitor(
|
fn deserialize_field_visitor(
|
||||||
field_names: Vec<String>,
|
fields: Vec<(String, Ident)>,
|
||||||
item_attrs: &attr::Item,
|
item_attrs: &attr::Item,
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
// Create the field names for the fields.
|
let field_strs = fields.iter().map(|&(ref name, _)| name);
|
||||||
let field_idents: Vec<_> = (0 .. field_names.len())
|
let field_bytes = fields.iter().map(|&(ref name, _)| quote::ByteStr(name));
|
||||||
.map(|i| aster::id(format!("__field{}", i)))
|
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
let ignore_variant = if item_attrs.deny_unknown_fields() {
|
let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(quote!(__ignore,))
|
Some(quote!(__ignore,))
|
||||||
};
|
};
|
||||||
|
|
||||||
let index_field_arms: Vec<_> = field_idents.iter()
|
let visit_index = if is_variant {
|
||||||
.enumerate()
|
let variant_indices = 0u32..;
|
||||||
.map(|(field_index, field_ident)| {
|
let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
|
||||||
quote! {
|
Some(quote! {
|
||||||
#field_index => { Ok(__Field::#field_ident) }
|
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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
|
||||||
|
|
||||||
let (index_error_msg, unknown_ident) = if is_variant {
|
|
||||||
("expected a variant", aster::id("unknown_variant"))
|
|
||||||
} else {
|
} else {
|
||||||
("expected a field", aster::id("unknown_field"))
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let fallthrough_index_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() {
|
let fallthrough_arm = if is_variant {
|
||||||
|
quote! {
|
||||||
|
Err(_serde::de::Error::unknown_variant(value, VARIANTS))
|
||||||
|
}
|
||||||
|
} else if item_attrs.deny_unknown_fields() {
|
||||||
|
quote! {
|
||||||
|
Err(_serde::de::Error::unknown_field(value, FIELDS))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
Ok(__Field::__ignore)
|
Ok(__Field::__ignore)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
quote! {
|
|
||||||
Err(_serde::de::Error::invalid_value(#index_error_msg))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let index_body = quote! {
|
let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() {
|
||||||
match value {
|
Some(quote! {
|
||||||
#(#index_field_arms)*
|
// TODO https://github.com/serde-rs/serde/issues/666
|
||||||
_ => #fallthrough_index_arm_expr
|
// update this to use str::from_utf8(value).unwrap_or("���") on no_std
|
||||||
}
|
let value = &_serde::export::from_utf8_lossy(value);
|
||||||
};
|
|
||||||
|
|
||||||
// Match arms to extract a field from a string
|
|
||||||
let str_field_arms: Vec<_> = field_idents.iter().zip(field_names.iter())
|
|
||||||
.map(|(field_ident, field_name)| {
|
|
||||||
quote! {
|
|
||||||
#field_name => { Ok(__Field::#field_ident) }
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fallthrough_str_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() {
|
|
||||||
quote! {
|
|
||||||
Ok(__Field::__ignore)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
None
|
||||||
Err(_serde::de::Error::#unknown_ident(value))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let str_body = quote! {
|
|
||||||
match value {
|
|
||||||
#(#str_field_arms)*
|
|
||||||
_ => #fallthrough_str_arm_expr
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Match arms to extract a field from a string
|
|
||||||
let bytes_field_arms: Vec<_> = field_idents.iter().zip(field_names.iter())
|
|
||||||
.map(|(field_ident, field_name)| {
|
|
||||||
let bytes_field_name = quote::ByteStr(field_name);
|
|
||||||
quote! {
|
|
||||||
#bytes_field_name => { Ok(__Field::#field_ident) }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fallthrough_bytes_arm_expr = if !is_variant && !item_attrs.deny_unknown_fields() {
|
|
||||||
quote! {
|
|
||||||
Ok(__Field::__ignore)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote!({
|
|
||||||
let value = ::std::string::String::from_utf8_lossy(value);
|
|
||||||
Err(_serde::de::Error::#unknown_ident(&value))
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let bytes_body = quote! {
|
|
||||||
match value {
|
|
||||||
#(#bytes_field_arms)*
|
|
||||||
_ => #fallthrough_bytes_arm_expr
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
@@ -744,32 +744,45 @@ fn deserialize_field_visitor(
|
|||||||
#ignore_variant
|
#ignore_variant
|
||||||
}
|
}
|
||||||
|
|
||||||
impl _serde::de::Deserialize for __Field {
|
impl _serde::Deserialize for __Field {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<__Field, __D::Error>
|
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<__Field, __D::Error>
|
||||||
where __D: _serde::de::Deserializer,
|
where __D: _serde::Deserializer,
|
||||||
{
|
{
|
||||||
struct __FieldVisitor;
|
struct __FieldVisitor;
|
||||||
|
|
||||||
impl _serde::de::Visitor for __FieldVisitor {
|
impl _serde::de::Visitor for __FieldVisitor {
|
||||||
type Value = __Field;
|
type Value = __Field;
|
||||||
|
|
||||||
fn visit_usize<__E>(&mut self, value: usize) -> ::std::result::Result<__Field, __E>
|
fn expecting(&self, formatter: &mut _serde::export::fmt::Formatter) -> _serde::export::fmt::Result {
|
||||||
where __E: _serde::de::Error
|
formatter.write_str("field name")
|
||||||
{
|
|
||||||
#index_body
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<__E>(&mut self, value: &str) -> ::std::result::Result<__Field, __E>
|
#visit_index
|
||||||
|
|
||||||
|
fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
#str_body
|
match value {
|
||||||
|
#(
|
||||||
|
#field_strs => Ok(__Field::#field_idents),
|
||||||
|
)*
|
||||||
|
_ => #fallthrough_arm
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<__E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, __E>
|
fn visit_bytes<__E>(self, value: &[u8]) -> _serde::export::Result<__Field, __E>
|
||||||
where __E: _serde::de::Error
|
where __E: _serde::de::Error
|
||||||
{
|
{
|
||||||
#bytes_body
|
match value {
|
||||||
|
#(
|
||||||
|
#field_bytes => Ok(__Field::#field_idents),
|
||||||
|
)*
|
||||||
|
_ => {
|
||||||
|
#bytes_to_str
|
||||||
|
#fallthrough_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,12 +799,21 @@ fn deserialize_struct_visitor(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
item_attrs: &attr::Item,
|
item_attrs: &attr::Item,
|
||||||
) -> (Tokens, Tokens, Tokens) {
|
) -> (Tokens, Tokens, Tokens) {
|
||||||
let field_exprs = fields.iter()
|
let field_names_idents: Vec<_> = fields.iter()
|
||||||
.map(|field| field.attrs.name().deserialize_name())
|
.enumerate()
|
||||||
|
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
||||||
|
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
|
||||||
.collect();
|
.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(
|
let field_visitor = deserialize_field_visitor(
|
||||||
field_exprs,
|
field_names_idents,
|
||||||
item_attrs,
|
item_attrs,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
@@ -804,14 +826,6 @@ fn deserialize_struct_visitor(
|
|||||||
item_attrs,
|
item_attrs,
|
||||||
);
|
);
|
||||||
|
|
||||||
let field_names = fields.iter().map(|field| {
|
|
||||||
field.ident.clone().expect("struct contains unnamed field").to_string()
|
|
||||||
});
|
|
||||||
|
|
||||||
let fields_stmt = quote! {
|
|
||||||
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
|
||||||
};
|
|
||||||
|
|
||||||
(field_visitor, fields_stmt, visit_map)
|
(field_visitor, fields_stmt, visit_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,22 +837,20 @@ fn deserialize_map(
|
|||||||
item_attrs: &attr::Item,
|
item_attrs: &attr::Item,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
// Create the field names for the fields.
|
// Create the field names for the fields.
|
||||||
let fields_names = fields.iter()
|
let fields_names: Vec<_> = fields.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, field)|
|
.map(|(i, field)| (field, field_i(i)))
|
||||||
(field, aster::id(format!("__field{}", i))))
|
.collect();
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Declare each field that will be deserialized.
|
// Declare each field that will be deserialized.
|
||||||
let let_values: Vec<_> = fields_names.iter()
|
let let_values = fields_names.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(|&(field, ref name)| {
|
.map(|&(field, ref name)| {
|
||||||
let field_ty = &field.ty;
|
let field_ty = &field.ty;
|
||||||
quote! {
|
quote! {
|
||||||
let mut #name: Option<#field_ty> = None;
|
let mut #name: Option<#field_ty> = None;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Match arms to extract a value for a field.
|
// Match arms to extract a value for a field.
|
||||||
let value_arms = fields_names.iter()
|
let value_arms = fields_names.iter()
|
||||||
@@ -871,21 +883,7 @@ fn deserialize_map(
|
|||||||
#name = Some(#visit);
|
#name = Some(#visit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Match arms to ignore value for fields that have `skip_deserializing`.
|
|
||||||
// Ignored even if `deny_unknown_fields` is set.
|
|
||||||
let skipped_arms = fields_names.iter()
|
|
||||||
.filter(|&&(field, _)| field.attrs.skip_deserializing())
|
|
||||||
.map(|&(_, ref name)| {
|
|
||||||
quote! {
|
|
||||||
__Field::#name => {
|
|
||||||
let _ = try!(visitor.visit_value::<_serde::de::impls::IgnoredAny>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Visit ignored values to consume them
|
// Visit ignored values to consume them
|
||||||
let ignored_arm = if item_attrs.deny_unknown_fields() {
|
let ignored_arm = if item_attrs.deny_unknown_fields() {
|
||||||
@@ -896,6 +894,24 @@ fn deserialize_map(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
||||||
|
let match_keys = if item_attrs.deny_unknown_fields() && all_skipped {
|
||||||
|
quote! {
|
||||||
|
// FIXME: Once we drop support for Rust 1.15:
|
||||||
|
// let None::<__Field> = try!(visitor.visit_key());
|
||||||
|
try!(visitor.visit_key::<__Field>()).map(|impossible| match impossible {});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
while let Some(key) = try!(visitor.visit_key::<__Field>()) {
|
||||||
|
match key {
|
||||||
|
#(#value_arms)*
|
||||||
|
#ignored_arm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let extract_values = fields_names.iter()
|
let extract_values = fields_names.iter()
|
||||||
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
|
||||||
.map(|&(field, ref name)| {
|
.map(|&(field, ref name)| {
|
||||||
@@ -907,8 +923,7 @@ fn deserialize_map(
|
|||||||
None => #missing_expr
|
None => #missing_expr
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let result = fields_names.iter()
|
let result = fields_names.iter()
|
||||||
.map(|&(field, ref name)| {
|
.map(|&(field, ref name)| {
|
||||||
@@ -924,15 +939,7 @@ fn deserialize_map(
|
|||||||
quote! {
|
quote! {
|
||||||
#(#let_values)*
|
#(#let_values)*
|
||||||
|
|
||||||
while let Some(key) = try!(visitor.visit_key::<__Field>()) {
|
#match_keys
|
||||||
match key {
|
|
||||||
#(#value_arms)*
|
|
||||||
#(#skipped_arms)*
|
|
||||||
#ignored_arm
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try!(visitor.end());
|
|
||||||
|
|
||||||
#(#extract_values)*
|
#(#extract_values)*
|
||||||
|
|
||||||
@@ -940,6 +947,10 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn field_i(i: usize) -> Ident {
|
||||||
|
Ident::new(format!("__field{}", i))
|
||||||
|
}
|
||||||
|
|
||||||
/// This function wraps the expression in `#[serde(deserialize_with="...")]` in
|
/// This function wraps the expression in `#[serde(deserialize_with="...")]` in
|
||||||
/// a trait to prevent it from accessing the internal `Deserialize` state.
|
/// a trait to prevent it from accessing the internal `Deserialize` state.
|
||||||
fn wrap_deserialize_with(
|
fn wrap_deserialize_with(
|
||||||
@@ -970,18 +981,18 @@ fn wrap_deserialize_with(
|
|||||||
quote! {
|
quote! {
|
||||||
struct __SerdeDeserializeWithStruct #impl_generics #where_clause {
|
struct __SerdeDeserializeWithStruct #impl_generics #where_clause {
|
||||||
value: #field_ty,
|
value: #field_ty,
|
||||||
phantom: ::std::marker::PhantomData<#phantom_ty>,
|
phantom: _serde::export::PhantomData<#phantom_ty>,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics _serde::de::Deserialize for #wrapper_ty #where_clause {
|
impl #impl_generics _serde::Deserialize for #wrapper_ty #where_clause {
|
||||||
fn deserialize<__D>(__d: &mut __D) -> ::std::result::Result<Self, __D::Error>
|
fn deserialize<__D>(__d: __D) -> _serde::export::Result<Self, __D::Error>
|
||||||
where __D: _serde::de::Deserializer
|
where __D: _serde::Deserializer
|
||||||
{
|
{
|
||||||
let value = try!(#deserialize_with(__d));
|
let value = try!(#deserialize_with(__d));
|
||||||
Ok(__SerdeDeserializeWithStruct {
|
Ok(__SerdeDeserializeWithStruct {
|
||||||
value: value,
|
value: value,
|
||||||
phantom: ::std::marker::PhantomData,
|
phantom: _serde::export::PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -993,7 +1004,7 @@ fn wrap_deserialize_with(
|
|||||||
fn expr_is_missing(attrs: &attr::Field) -> Tokens {
|
fn expr_is_missing(attrs: &attr::Field) -> Tokens {
|
||||||
match *attrs.default() {
|
match *attrs.default() {
|
||||||
attr::FieldDefault::Default => {
|
attr::FieldDefault::Default => {
|
||||||
return quote!(::std::default::Default::default());
|
return quote!(_serde::export::Default::default());
|
||||||
}
|
}
|
||||||
attr::FieldDefault::Path(ref path) => {
|
attr::FieldDefault::Path(ref path) => {
|
||||||
return quote!(#path());
|
return quote!(#path());
|
||||||
@@ -1005,7 +1016,7 @@ fn expr_is_missing(attrs: &attr::Field) -> Tokens {
|
|||||||
match attrs.deserialize_with() {
|
match attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
try!(visitor.missing_field(#name))
|
try!(_serde::de::private::missing_field(#name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
|
|||||||
+29
-106
@@ -2,7 +2,6 @@
|
|||||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||||
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
||||||
#![cfg_attr(feature = "clippy", allow(used_underscore_binding))]
|
#![cfg_attr(feature = "clippy", allow(used_underscore_binding))]
|
||||||
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
|
|
||||||
|
|
||||||
// The `quote!` macro requires deep recursion.
|
// The `quote!` macro requires deep recursion.
|
||||||
#![recursion_limit = "192"]
|
#![recursion_limit = "192"]
|
||||||
@@ -13,29 +12,15 @@ extern crate serde_codegen_internals as internals;
|
|||||||
extern crate syntex;
|
extern crate syntex;
|
||||||
|
|
||||||
#[cfg(feature = "with-syntex")]
|
#[cfg(feature = "with-syntex")]
|
||||||
#[macro_use]
|
|
||||||
extern crate syntex_syntax as syntax;
|
extern crate syntex_syntax as syntax;
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate syntax;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
extern crate rustc_plugin;
|
|
||||||
|
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
#[cfg(feature = "with-syntex")]
|
#[cfg(feature = "with-syntex")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
use syntax::feature_gate::AttributeType;
|
|
||||||
|
|
||||||
mod bound;
|
mod bound;
|
||||||
mod de;
|
mod de;
|
||||||
mod ser;
|
mod ser;
|
||||||
@@ -52,11 +37,11 @@ fn syntex_registry() -> syntex::Registry {
|
|||||||
|
|
||||||
impl fold::Folder for StripAttributeFolder {
|
impl fold::Folder for StripAttributeFolder {
|
||||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||||
match attr.node.value.node {
|
if attr.value.name == "serde" {
|
||||||
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
|
if let ast::MetaItemKind::List(..) = attr.value.node {
|
||||||
_ => {}
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(attr)
|
Some(attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +58,8 @@ fn syntex_registry() -> syntex::Registry {
|
|||||||
reg.add_attr("feature(custom_derive)");
|
reg.add_attr("feature(custom_derive)");
|
||||||
reg.add_attr("feature(custom_attribute)");
|
reg.add_attr("feature(custom_attribute)");
|
||||||
|
|
||||||
reg.add_decorator("derive_Serialize", expand_derive_serialize);
|
reg.add_decorator("derive_Serialize", shim::expand_derive_serialize);
|
||||||
reg.add_decorator("derive_Deserialize", expand_derive_deserialize);
|
reg.add_decorator("derive_Deserialize", shim::expand_derive_deserialize);
|
||||||
|
|
||||||
reg.add_post_expansion_pass(strip_attributes);
|
reg.add_post_expansion_pass(strip_attributes);
|
||||||
|
|
||||||
@@ -107,24 +92,9 @@ pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
|
|||||||
syntex::with_extra_stack(expand_thread)
|
syntex::with_extra_stack(expand_thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
pub fn register(reg: &mut rustc_plugin::Registry) {
|
|
||||||
reg.register_syntax_extension(
|
|
||||||
syntax::parse::token::intern("derive_Serialize"),
|
|
||||||
syntax::ext::base::MultiDecorator(
|
|
||||||
Box::new(expand_derive_serialize)));
|
|
||||||
|
|
||||||
reg.register_syntax_extension(
|
|
||||||
syntax::parse::token::intern("derive_Deserialize"),
|
|
||||||
syntax::ext::base::MultiDecorator(
|
|
||||||
Box::new(expand_derive_deserialize)));
|
|
||||||
|
|
||||||
reg.register_attribute("serde".to_owned(), AttributeType::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! shim {
|
macro_rules! shim {
|
||||||
($name:ident $pkg:ident :: $func:ident) => {
|
($name:ident $pkg:ident :: $func:ident) => {
|
||||||
fn $func(
|
pub fn $func(
|
||||||
cx: &mut ::syntax::ext::base::ExtCtxt,
|
cx: &mut ::syntax::ext::base::ExtCtxt,
|
||||||
span: ::syntax::codemap::Span,
|
span: ::syntax::codemap::Span,
|
||||||
meta_item: &::syntax::ast::MetaItem,
|
meta_item: &::syntax::ast::MetaItem,
|
||||||
@@ -145,13 +115,12 @@ macro_rules! shim {
|
|||||||
|
|
||||||
use syntax::{attr, ast, visit};
|
use syntax::{attr, ast, visit};
|
||||||
struct MarkSerdeAttributesUsed;
|
struct MarkSerdeAttributesUsed;
|
||||||
impl visit::Visitor for MarkSerdeAttributesUsed {
|
impl<'a> visit::Visitor<'a> for MarkSerdeAttributesUsed {
|
||||||
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||||
match attr.node.value.node {
|
if attr.value.name == "serde" {
|
||||||
ast::MetaItemKind::List(ref name, _) if name == "serde" => {
|
if let ast::MetaItemKind::List(..) = attr.value.node {
|
||||||
attr::mark_used(attr);
|
attr::mark_used(attr);
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,6 +129,7 @@ macro_rules! shim {
|
|||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
let s = pprust::item_to_string(item);
|
let s = pprust::item_to_string(item);
|
||||||
|
|
||||||
|
use {syn, $pkg};
|
||||||
let syn_item = syn::parse_macro_input(&s).unwrap();
|
let syn_item = syn::parse_macro_input(&s).unwrap();
|
||||||
let expanded = match $pkg::$func(&syn_item) {
|
let expanded = match $pkg::$func(&syn_item) {
|
||||||
Ok(expanded) => expanded.to_string(),
|
Ok(expanded) => expanded.to_string(),
|
||||||
@@ -171,78 +141,31 @@ macro_rules! shim {
|
|||||||
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
let name = stringify!($name).to_string();
|
let name = stringify!($name).to_string();
|
||||||
let cfg = Vec::new();
|
|
||||||
let sess = cx.parse_sess;
|
let sess = cx.parse_sess;
|
||||||
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, sess);
|
let impl_item = parse::parse_item_from_source_str(name, expanded, sess);
|
||||||
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
|
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
shim!(Serialize ser::expand_derive_serialize);
|
#[cfg(feature = "with-syntex")]
|
||||||
shim!(Deserialize de::expand_derive_deserialize);
|
mod shim {
|
||||||
|
shim!(Serialize ser::expand_derive_serialize);
|
||||||
|
shim!(Deserialize de::expand_derive_deserialize);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
#[cfg(feature = "with-syn")]
|
||||||
pub fn expand_single_item(item: &str) -> Result<String, String> {
|
#[doc(hidden)]
|
||||||
|
/// Not public API. Use the serde_derive crate.
|
||||||
|
pub fn expand_derive_serialize(item: &str) -> Result<quote::Tokens, String> {
|
||||||
let syn_item = syn::parse_macro_input(item).unwrap();
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
let (ser, de, syn_item) = strip_serde_derives(syn_item);
|
ser::expand_derive_serialize(&syn_item)
|
||||||
let expanded_ser = if ser {
|
}
|
||||||
Some(try!(ser::expand_derive_serialize(&syn_item)))
|
|
||||||
} else {
|
#[cfg(feature = "with-syn")]
|
||||||
None
|
#[doc(hidden)]
|
||||||
};
|
/// Not public API. Use the serde_derive crate.
|
||||||
let expanded_de = if de {
|
pub fn expand_derive_deserialize(item: &str) -> Result<quote::Tokens, String> {
|
||||||
Some(try!(de::expand_derive_deserialize(&syn_item)))
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
} else {
|
de::expand_derive_deserialize(&syn_item)
|
||||||
None::<quote::Tokens>
|
|
||||||
};
|
|
||||||
let syn_item = post_expansion::strip_attrs_later(syn_item, &["serde"], "serde");
|
|
||||||
return Ok(quote!(#expanded_ser #expanded_de #syn_item).to_string());
|
|
||||||
|
|
||||||
fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) {
|
|
||||||
let mut ser = false;
|
|
||||||
let mut de = false;
|
|
||||||
let item = syn::MacroInput {
|
|
||||||
attrs: item.attrs.into_iter().flat_map(|attr| {
|
|
||||||
if attr.is_sugared_doc || attr.style != syn::AttrStyle::Outer {
|
|
||||||
return Some(attr);
|
|
||||||
}
|
|
||||||
let (name, nested) = match attr.value {
|
|
||||||
syn::MetaItem::List(name, nested) => (name, nested),
|
|
||||||
_ => return Some(attr)
|
|
||||||
};
|
|
||||||
if name != "derive" {
|
|
||||||
return Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, nested),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let rest: Vec<_> = nested.into_iter().filter(|nested| {
|
|
||||||
match *nested {
|
|
||||||
syn::MetaItem::Word(ref word) if word == "Serialize" => {
|
|
||||||
ser = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
syn::MetaItem::Word(ref word) if word == "Deserialize" => {
|
|
||||||
de = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
if rest.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, rest),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).collect(),
|
|
||||||
..item
|
|
||||||
};
|
|
||||||
(ser, de, item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+97
-93
@@ -1,4 +1,4 @@
|
|||||||
use syn::{self, aster};
|
use syn::{self, aster, Ident};
|
||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
|
|
||||||
use bound;
|
use bound;
|
||||||
@@ -22,16 +22,16 @@ pub fn expand_derive_serialize(item: &syn::MacroInput) -> Result<Tokens, String>
|
|||||||
|
|
||||||
let where_clause = &impl_generics.where_clause;
|
let where_clause = &impl_generics.where_clause;
|
||||||
|
|
||||||
let dummy_const = aster::id(format!("_IMPL_SERIALIZE_FOR_{}", item.ident));
|
let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", item.ident));
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||||
const #dummy_const: () = {
|
const #dummy_const: () = {
|
||||||
extern crate serde as _serde;
|
extern crate serde as _serde;
|
||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics _serde::ser::Serialize for #ty #where_clause {
|
impl #impl_generics _serde::Serialize for #ty #where_clause {
|
||||||
fn serialize<__S>(&self, _serializer: &mut __S) -> ::std::result::Result<(), __S::Error>
|
fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::ser::Serializer
|
where __S: _serde::Serializer
|
||||||
{
|
{
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ fn build_impl_generics(item: &Item) -> syn::Generics {
|
|||||||
None => {
|
None => {
|
||||||
bound::with_bound(item, &generics,
|
bound::with_bound(item, &generics,
|
||||||
needs_serialize_bound,
|
needs_serialize_bound,
|
||||||
&aster::path().ids(&["_serde", "ser", "Serialize"]).build())
|
&aster::path().ids(&["_serde", "Serialize"]).build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +159,7 @@ fn serialize_tuple_struct(
|
|||||||
fields,
|
fields,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
false,
|
false,
|
||||||
aster::id("serialize_tuple_struct_elt"),
|
quote!(_serde::ser::SerializeTupleStruct::serialize_field),
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = item_attrs.name().serialize_name();
|
let type_name = item_attrs.name().serialize_name();
|
||||||
@@ -169,7 +169,7 @@ fn serialize_tuple_struct(
|
|||||||
quote! {
|
quote! {
|
||||||
let #let_mut __serde_state = try!(_serializer.serialize_tuple_struct(#type_name, #len));
|
let #let_mut __serde_state = try!(_serializer.serialize_tuple_struct(#type_name, #len));
|
||||||
#(#serialize_stmts)*
|
#(#serialize_stmts)*
|
||||||
_serializer.serialize_tuple_struct_end(__serde_state)
|
_serde::ser::SerializeTupleStruct::end(__serde_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ fn serialize_struct(
|
|||||||
fields,
|
fields,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
false,
|
false,
|
||||||
aster::id("serialize_struct_elt"),
|
quote!(_serde::ser::SerializeStruct::serialize_field),
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = item_attrs.name().serialize_name();
|
let type_name = item_attrs.name().serialize_name();
|
||||||
@@ -210,7 +210,7 @@ fn serialize_struct(
|
|||||||
quote! {
|
quote! {
|
||||||
let #let_mut __serde_state = try!(_serializer.serialize_struct(#type_name, #len));
|
let #let_mut __serde_state = try!(_serializer.serialize_struct(#type_name, #len));
|
||||||
#(#serialize_fields)*
|
#(#serialize_fields)*
|
||||||
_serializer.serialize_struct_end(__serde_state)
|
_serde::ser::SerializeStruct::end(__serde_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,76 +256,80 @@ fn serialize_variant(
|
|||||||
let variant_ident = variant.ident.clone();
|
let variant_ident = variant.ident.clone();
|
||||||
let variant_name = variant.attrs.name().serialize_name();
|
let variant_name = variant.attrs.name().serialize_name();
|
||||||
|
|
||||||
match variant.style {
|
if variant.attrs.skip_serializing() {
|
||||||
Style::Unit => {
|
let skipped_msg = format!("the enum variant {}::{} cannot be serialized",
|
||||||
quote! {
|
type_ident, variant_ident);
|
||||||
#type_ident::#variant_ident =>
|
let skipped_err = quote! {
|
||||||
_serde::ser::Serializer::serialize_unit_variant(
|
Err(_serde::ser::Error::custom(#skipped_msg))
|
||||||
_serializer,
|
};
|
||||||
#type_name,
|
let fields_pat = match variant.style {
|
||||||
#variant_index,
|
Style::Unit => quote!(),
|
||||||
#variant_name,
|
Style::Newtype | Style::Tuple => quote!( (..) ),
|
||||||
),
|
Style::Struct => quote!( {..} ),
|
||||||
}
|
};
|
||||||
},
|
quote! {
|
||||||
Style::Newtype => {
|
#type_ident::#variant_ident #fields_pat => #skipped_err,
|
||||||
let block = serialize_newtype_variant(
|
|
||||||
type_name,
|
|
||||||
variant_index,
|
|
||||||
variant_name,
|
|
||||||
ty,
|
|
||||||
generics,
|
|
||||||
&variant.fields[0],
|
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#type_ident::#variant_ident(ref __simple_value) => #block,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Style::Tuple => {
|
|
||||||
let field_names: Vec<Tokens> = (0 .. variant.fields.len())
|
|
||||||
.map(|i| {
|
|
||||||
let id = aster::id(format!("__field{}", i));
|
|
||||||
quote!(ref #id)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let pat = quote!(#type_ident::#variant_ident(#(#field_names),*));
|
|
||||||
|
|
||||||
let block = serialize_tuple_variant(
|
|
||||||
type_name,
|
|
||||||
variant_index,
|
|
||||||
variant_name,
|
|
||||||
generics,
|
|
||||||
ty,
|
|
||||||
&variant.fields,
|
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#pat => { #block }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
} else { // variant wasn't skipped
|
||||||
let fields = variant.fields.iter().map(|field| {
|
match variant.style {
|
||||||
let id = match field.ident {
|
Style::Unit => {
|
||||||
Some(ref name) => name.clone(),
|
quote! {
|
||||||
None => panic!("struct variant has unnamed fields"),
|
#type_ident::#variant_ident =>
|
||||||
};
|
_serde::Serializer::serialize_unit_variant(
|
||||||
quote!(ref #id)
|
_serializer,
|
||||||
});
|
#type_name,
|
||||||
let pat = quote!(#type_ident::#variant_ident { #(#fields),* });
|
#variant_index,
|
||||||
|
#variant_name,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Style::Newtype => {
|
||||||
|
let block = serialize_newtype_variant(
|
||||||
|
type_name,
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
ty,
|
||||||
|
generics,
|
||||||
|
&variant.fields[0],
|
||||||
|
);
|
||||||
|
|
||||||
let block = serialize_struct_variant(
|
quote! {
|
||||||
variant_index,
|
#type_ident::#variant_ident(ref __simple_value) => #block,
|
||||||
variant_name,
|
}
|
||||||
generics,
|
},
|
||||||
ty,
|
Style::Tuple => {
|
||||||
&variant.fields,
|
let field_names = (0 .. variant.fields.len())
|
||||||
item_attrs,
|
.map(|i| Ident::new(format!("__field{}", i)));
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
let block = serialize_tuple_variant(
|
||||||
#pat => { #block }
|
type_name,
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
generics,
|
||||||
|
ty,
|
||||||
|
&variant.fields,
|
||||||
|
);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#type_ident::#variant_ident(#(ref #field_names),*) => { #block }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Style::Struct => {
|
||||||
|
let fields = variant.fields.iter()
|
||||||
|
.map(|f| f.ident.clone().expect("struct variant has unnamed fields"));
|
||||||
|
|
||||||
|
let block = serialize_struct_variant(
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
generics,
|
||||||
|
ty,
|
||||||
|
&variant.fields,
|
||||||
|
item_attrs,
|
||||||
|
);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#type_ident::#variant_ident { #(ref #fields),* } => { #block }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +350,7 @@ fn serialize_newtype_variant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
_serde::ser::Serializer::serialize_newtype_variant(
|
_serde::Serializer::serialize_newtype_variant(
|
||||||
_serializer,
|
_serializer,
|
||||||
#type_name,
|
#type_name,
|
||||||
#variant_index,
|
#variant_index,
|
||||||
@@ -369,7 +373,7 @@ fn serialize_tuple_variant(
|
|||||||
fields,
|
fields,
|
||||||
generics,
|
generics,
|
||||||
true,
|
true,
|
||||||
aster::id("serialize_tuple_variant_elt"),
|
quote!(_serde::ser::SerializeTupleVariant::serialize_field),
|
||||||
);
|
);
|
||||||
|
|
||||||
let len = serialize_stmts.len();
|
let len = serialize_stmts.len();
|
||||||
@@ -382,7 +386,7 @@ fn serialize_tuple_variant(
|
|||||||
#variant_name,
|
#variant_name,
|
||||||
#len));
|
#len));
|
||||||
#(#serialize_stmts)*
|
#(#serialize_stmts)*
|
||||||
_serializer.serialize_tuple_variant_end(__serde_state)
|
_serde::ser::SerializeTupleVariant::end(__serde_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +403,7 @@ fn serialize_struct_variant(
|
|||||||
fields,
|
fields,
|
||||||
generics,
|
generics,
|
||||||
true,
|
true,
|
||||||
aster::id("serialize_struct_variant_elt"),
|
quote!(_serde::ser::SerializeStructVariant::serialize_field),
|
||||||
);
|
);
|
||||||
|
|
||||||
let item_name = item_attrs.name().serialize_name();
|
let item_name = item_attrs.name().serialize_name();
|
||||||
@@ -429,7 +433,7 @@ fn serialize_struct_variant(
|
|||||||
#len,
|
#len,
|
||||||
));
|
));
|
||||||
#(#serialize_fields)*
|
#(#serialize_fields)*
|
||||||
_serializer.serialize_struct_variant_end(__serde_state)
|
_serde::ser::SerializeStructVariant::end(__serde_state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,16 +442,16 @@ fn serialize_tuple_struct_visitor(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
generics: &syn::Generics,
|
generics: &syn::Generics,
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
func: syn::Ident,
|
func: Tokens,
|
||||||
) -> Vec<Tokens> {
|
) -> Vec<Tokens> {
|
||||||
fields.iter()
|
fields.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, field)| {
|
.map(|(i, field)| {
|
||||||
let mut field_expr = if is_enum {
|
let mut field_expr = if is_enum {
|
||||||
let id = aster::id(format!("__field{}", i));
|
let id = Ident::new(format!("__field{}", i));
|
||||||
quote!(#id)
|
quote!(#id)
|
||||||
} else {
|
} else {
|
||||||
let i = aster::id(i);
|
let i = Ident::new(i);
|
||||||
quote!(&self.#i)
|
quote!(&self.#i)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -460,7 +464,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ser = quote! {
|
let ser = quote! {
|
||||||
try!(_serializer.#func(&mut __serde_state, #field_expr));
|
try!(#func(&mut __serde_state, #field_expr));
|
||||||
};
|
};
|
||||||
|
|
||||||
match skip {
|
match skip {
|
||||||
@@ -476,7 +480,7 @@ fn serialize_struct_visitor(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
generics: &syn::Generics,
|
generics: &syn::Generics,
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
func: syn::Ident,
|
func: Tokens,
|
||||||
) -> Vec<Tokens> {
|
) -> Vec<Tokens> {
|
||||||
fields.iter()
|
fields.iter()
|
||||||
.filter(|&field| !field.attrs.skip_serializing())
|
.filter(|&field| !field.attrs.skip_serializing())
|
||||||
@@ -499,7 +503,7 @@ fn serialize_struct_visitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let ser = quote! {
|
let ser = quote! {
|
||||||
try!(_serializer.#func(&mut __serde_state, #key_expr, #field_expr));
|
try!(#func(&mut __serde_state, #key_expr, #field_expr));
|
||||||
};
|
};
|
||||||
|
|
||||||
match skip {
|
match skip {
|
||||||
@@ -536,15 +540,15 @@ fn wrap_serialize_with(
|
|||||||
phantom: ::std::marker::PhantomData<#item_ty>,
|
phantom: ::std::marker::PhantomData<#item_ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #wrapper_generics _serde::ser::Serialize for #wrapper_ty #where_clause {
|
impl #wrapper_generics _serde::Serialize for #wrapper_ty #where_clause {
|
||||||
fn serialize<__S>(&self, __s: &mut __S) -> ::std::result::Result<(), __S::Error>
|
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::ser::Serializer
|
where __S: _serde::Serializer
|
||||||
{
|
{
|
||||||
#path(self.value, __s)
|
#path(self.value, __s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__SerializeWith {
|
&__SerializeWith {
|
||||||
value: #value,
|
value: #value,
|
||||||
phantom: ::std::marker::PhantomData::<#item_ty>,
|
phantom: ::std::marker::PhantomData::<#item_ty>,
|
||||||
}
|
}
|
||||||
@@ -554,7 +558,7 @@ fn wrap_serialize_with(
|
|||||||
// Serialization of an empty struct results in code like:
|
// Serialization of an empty struct results in code like:
|
||||||
//
|
//
|
||||||
// let mut __serde_state = try!(serializer.serialize_struct("S", 0));
|
// let mut __serde_state = try!(serializer.serialize_struct("S", 0));
|
||||||
// serializer.serialize_struct_end(__serde_state)
|
// _serde::ser::SerializeStruct::end(__serde_state)
|
||||||
//
|
//
|
||||||
// where we want to omit the `mut` to avoid a warning.
|
// where we want to omit the `mut` to avoid a warning.
|
||||||
fn mut_if(is_mut: bool) -> Option<Tokens> {
|
fn mut_if(is_mut: bool) -> Option<Tokens> {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen_internals"
|
name = "serde_codegen_internals"
|
||||||
version = "0.10.0"
|
version = "0.11.3"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "AST representation used by Serde codegen. Unstable."
|
description = "AST representation used by Serde codegen. Unstable."
|
||||||
@@ -14,5 +14,8 @@ include = ["Cargo.toml", "src/**/*.rs"]
|
|||||||
unstable-testing = ["clippy"]
|
unstable-testing = ["clippy"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "0.*", optional = true }
|
||||||
syn = "0.9"
|
syn = "0.10"
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use Ctxt;
|
use Ctxt;
|
||||||
use syn;
|
use syn;
|
||||||
|
use syn::MetaItem::{List, NameValue, Word};
|
||||||
|
use syn::NestedMetaItem::{Literal, MetaItem};
|
||||||
|
|
||||||
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
||||||
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
|
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
|
||||||
@@ -105,7 +107,7 @@ impl Item {
|
|||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -113,7 +115,7 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
@@ -121,12 +123,12 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(deny_unknown_fields)]`
|
// Parse `#[serde(deny_unknown_fields)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "deny_unknown_fields" => {
|
MetaItem(Word(ref name)) if name == "deny_unknown_fields" => {
|
||||||
deny_unknown_fields.set_true();
|
deny_unknown_fields.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound="D: Serialize")]`
|
// Parse `#[serde(bound="D: Serialize")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
@@ -134,17 +136,21 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "bound" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
|
||||||
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
||||||
ser_bound.set_opt(ser);
|
ser_bound.set_opt(ser);
|
||||||
de_bound.set_opt(de);
|
de_bound.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde container attribute `{}`",
|
cx.error(format!("unknown serde container attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde container attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,18 +187,22 @@ impl Item {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
name: Name,
|
name: Name,
|
||||||
|
skip_deserializing: bool,
|
||||||
|
skip_serializing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Variant {
|
impl Variant {
|
||||||
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
|
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
|
||||||
let mut ser_name = Attr::none(cx, "rename");
|
let mut ser_name = Attr::none(cx, "rename");
|
||||||
let mut de_name = Attr::none(cx, "rename");
|
let mut de_name = Attr::none(cx, "rename");
|
||||||
|
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
|
||||||
|
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
|
||||||
|
|
||||||
for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
|
for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -200,17 +210,29 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Parse `#[serde(skip_deserializing)]`
|
||||||
|
MetaItem(Word(ref name)) if name == "skip_deserializing" => {
|
||||||
|
skip_deserializing.set_true();
|
||||||
|
}
|
||||||
|
// Parse `#[serde(skip_serializing)]`
|
||||||
|
MetaItem(Word(ref name)) if name == "skip_serializing" => {
|
||||||
|
skip_serializing.set_true();
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde variant attribute `{}`",
|
cx.error(format!("unknown serde variant attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde variant attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,12 +242,22 @@ impl Variant {
|
|||||||
serialize: ser_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
serialize: ser_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
||||||
deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
||||||
},
|
},
|
||||||
|
skip_deserializing: skip_deserializing.get(),
|
||||||
|
skip_serializing: skip_serializing.get(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &Name {
|
pub fn name(&self) -> &Name {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn skip_deserializing(&self) -> bool {
|
||||||
|
self.skip_deserializing
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn skip_serializing(&self) -> bool {
|
||||||
|
self.skip_serializing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents field attribute information
|
/// Represents field attribute information
|
||||||
@@ -278,7 +310,7 @@ impl Field {
|
|||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -286,7 +318,7 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
@@ -294,50 +326,50 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(default)]`
|
// Parse `#[serde(default)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "default" => {
|
MetaItem(Word(ref name)) if name == "default" => {
|
||||||
default.set(FieldDefault::Default);
|
default.set(FieldDefault::Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(default="...")]`
|
// Parse `#[serde(default="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "default" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
default.set(FieldDefault::Path(path));
|
default.set(FieldDefault::Path(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_serializing)]`
|
// Parse `#[serde(skip_serializing)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "skip_serializing" => {
|
MetaItem(Word(ref name)) if name == "skip_serializing" => {
|
||||||
skip_serializing.set_true();
|
skip_serializing.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_deserializing)]`
|
// Parse `#[serde(skip_deserializing)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "skip_deserializing" => {
|
MetaItem(Word(ref name)) if name == "skip_deserializing" => {
|
||||||
skip_deserializing.set_true();
|
skip_deserializing.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_serializing_if="...")]`
|
// Parse `#[serde(skip_serializing_if="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "skip_serializing_if" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
skip_serializing_if.set(path);
|
skip_serializing_if.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(serialize_with="...")]`
|
// Parse `#[serde(serialize_with="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "serialize_with" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
serialize_with.set(path);
|
serialize_with.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(deserialize_with="...")]`
|
// Parse `#[serde(deserialize_with="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "deserialize_with" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
deserialize_with.set(path);
|
deserialize_with.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound="D: Serialize")]`
|
// Parse `#[serde(bound="D: Serialize")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
@@ -345,17 +377,21 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "bound" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
|
||||||
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
||||||
ser_bound.set_opt(ser);
|
ser_bound.set_opt(ser);
|
||||||
de_bound.set_opt(de);
|
de_bound.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde field attribute `{}`",
|
cx.error(format!("unknown serde field attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde field attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +460,7 @@ type SerAndDe<T> = (Option<T>, Option<T>);
|
|||||||
fn get_ser_and_de<T, F>(
|
fn get_ser_and_de<T, F>(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
attr_name: &'static str,
|
attr_name: &'static str,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
f: F
|
f: F
|
||||||
) -> Result<SerAndDe<T>, ()>
|
) -> Result<SerAndDe<T>, ()>
|
||||||
where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
|
where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
|
||||||
@@ -434,13 +470,13 @@ fn get_ser_and_de<T, F>(
|
|||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
match *item {
|
match *item {
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "serialize" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "serialize" => {
|
||||||
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
||||||
ser_item.set(v);
|
ser_item.set(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "deserialize" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "deserialize" => {
|
||||||
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
||||||
de_item.set(v);
|
de_item.set(v);
|
||||||
}
|
}
|
||||||
@@ -459,21 +495,21 @@ fn get_ser_and_de<T, F>(
|
|||||||
|
|
||||||
fn get_renames(
|
fn get_renames(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
) -> Result<SerAndDe<String>, ()> {
|
) -> Result<SerAndDe<String>, ()> {
|
||||||
get_ser_and_de(cx, "rename", items, get_string_from_lit)
|
get_ser_and_de(cx, "rename", items, get_string_from_lit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_where_predicates(
|
fn get_where_predicates(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
|
) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
|
||||||
get_ser_and_de(cx, "bound", items, parse_lit_into_where)
|
get_ser_and_de(cx, "bound", items, parse_lit_into_where)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::MetaItem>> {
|
pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>> {
|
||||||
match attr.value {
|
match attr.value {
|
||||||
syn::MetaItem::List(ref name, ref items) if name == "serde" => {
|
List(ref name, ref items) if name == "serde" => {
|
||||||
Some(items.iter().cloned().collect())
|
Some(items.iter().cloned().collect())
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "0.8.16"
|
version = "0.9.1"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
@@ -10,21 +10,21 @@ documentation = "https://serde.rs/codegen.html"
|
|||||||
keywords = ["serde", "serialization"]
|
keywords = ["serde", "serialization"]
|
||||||
include = ["Cargo.toml", "src/**/*.rs"]
|
include = ["Cargo.toml", "src/**/*.rs"]
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
post-expansion = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies.serde_codegen]
|
[dependencies.serde_codegen]
|
||||||
version = "=0.8.16"
|
version = "=0.9.0"
|
||||||
path = "../serde_codegen"
|
path = "../serde_codegen"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["with-syn"]
|
features = ["with-syn"]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
compiletest_rs = "^0.2.0"
|
compiletest_rs = "0.2"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
serde = { version = "0.8.16", path = "../serde" }
|
serde = { version = "0.9", path = "../serde" }
|
||||||
serde_test = { version = "0.8.16", path = "../serde_test" }
|
serde_test = { version = "0.9", path = "../serde_test" }
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "serde_derive_tests_no_std"
|
||||||
|
version = "0.0.0"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { path = "../../serde", default-features = false }
|
||||||
|
serde_derive = { path = ".." }
|
||||||
@@ -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 },
|
||||||
|
}
|
||||||
+4
-14
@@ -1,30 +1,20 @@
|
|||||||
#![feature(proc_macro, proc_macro_lib)]
|
|
||||||
#![cfg(not(test))]
|
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate serde_codegen;
|
extern crate serde_codegen;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize)]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Serialize)]\n{}", input);
|
match serde_codegen::expand_derive_serialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Deserialize)]
|
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Deserialize)]\n{}", input);
|
match serde_codegen::expand_derive_deserialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_post_expansion!(PostExpansion_serde);
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#![feature(proc_macro)]
|
|
||||||
#![deny(identity_op)]
|
#![deny(identity_op)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![feature(test, proc_macro)]
|
#![feature(test)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "0.8.16"
|
version = "0.9.1"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
@@ -12,4 +12,7 @@ keywords = ["serde", "serialization"]
|
|||||||
include = ["Cargo.toml", "src/**/*.rs"]
|
include = ["Cargo.toml", "src/**/*.rs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "0.8.16", path = "../serde" }
|
serde = { version = "0.9", path = "../serde" }
|
||||||
|
|
||||||
|
[badges]
|
||||||
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
|
|||||||
+183
-222
@@ -3,12 +3,14 @@ use std::iter;
|
|||||||
use serde::de::{
|
use serde::de::{
|
||||||
self,
|
self,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
|
DeserializeSeed,
|
||||||
EnumVisitor,
|
EnumVisitor,
|
||||||
MapVisitor,
|
MapVisitor,
|
||||||
SeqVisitor,
|
SeqVisitor,
|
||||||
VariantVisitor,
|
VariantVisitor,
|
||||||
Visitor,
|
Visitor,
|
||||||
};
|
};
|
||||||
|
use serde::de::value::ValueDeserializer;
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
@@ -32,184 +34,207 @@ impl<I> Deserializer<I>
|
|||||||
self.tokens.next()
|
self.tokens.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
pub fn expect_token(&mut self, expected: Token) -> Result<(), Error> {
|
||||||
where V: Visitor,
|
match self.tokens.next() {
|
||||||
{
|
Some(token) => {
|
||||||
visitor.visit_seq(DeserializerSeqVisitor {
|
if expected == token {
|
||||||
de: self,
|
Ok(())
|
||||||
len: len,
|
} else {
|
||||||
})
|
Err(Error::UnexpectedToken(token))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Err(Error::EndOfTokens),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_array<V>(&mut self, len: usize, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_seq<V>(&mut self, len: Option<usize>, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_seq(DeserializerArrayVisitor {
|
let value = try!(visitor.visit_seq(DeserializerSeqVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::SeqEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_tuple<V>(&mut self, len: usize, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_array<V>(&mut self, len: usize, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_seq(DeserializerTupleVisitor {
|
let value = try!(visitor.visit_seq(DeserializerArrayVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::SeqEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_tuple_struct<V>(&mut self, len: usize, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_tuple<V>(&mut self, len: usize, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_seq(DeserializerTupleStructVisitor {
|
let value = try!(visitor.visit_seq(DeserializerTupleVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::TupleEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_variant_seq<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_tuple_struct<V>(&mut self, len: usize, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_seq(DeserializerVariantSeqVisitor {
|
let value = try!(visitor.visit_seq(DeserializerTupleStructVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::TupleStructEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_variant_seq<V>(&mut self, len: Option<usize>, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_map(DeserializerMapVisitor {
|
let value = try!(visitor.visit_seq(DeserializerVariantSeqVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::EnumSeqEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_struct<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_map<V>(&mut self, len: Option<usize>, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_map(DeserializerStructVisitor {
|
let value = try!(visitor.visit_map(DeserializerMapVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::MapEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_variant_map<V>(&mut self, len: Option<usize>, mut visitor: V) -> Result<V::Value, Error>
|
fn visit_struct<V>(&mut self, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
visitor.visit_map(DeserializerVariantMapVisitor {
|
let value = try!(visitor.visit_map(DeserializerStructVisitor {
|
||||||
|
de: self,
|
||||||
|
len: fields.len(),
|
||||||
|
}));
|
||||||
|
try!(self.expect_token(Token::StructEnd));
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_variant_map<V>(&mut self, len: Option<usize>, visitor: V) -> Result<V::Value, Error>
|
||||||
|
where V: Visitor,
|
||||||
|
{
|
||||||
|
let value = try!(visitor.visit_map(DeserializerVariantMapVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
len: len,
|
len: len,
|
||||||
})
|
}));
|
||||||
|
try!(self.expect_token(Token::EnumMapEnd));
|
||||||
|
Ok(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> de::Deserializer for Deserializer<I>
|
impl<'a, I> de::Deserializer for &'a mut Deserializer<I>
|
||||||
where I: Iterator<Item=Token<'static>>,
|
where I: Iterator<Item=Token<'static>>,
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn deserialize_seq<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_seq<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_struct_field<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_struct_field<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_map<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_map<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_unit<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_unit<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_bytes<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_bytes<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_ignored_any<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_byte_buf<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_string<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_ignored_any<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_str<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_string<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_char<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_str<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_i64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_char<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_i32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_i64<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_i16<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_i32<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_i8<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_i16<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_u64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_i8<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_u32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_u64<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_u16<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_u32<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_u8<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_u16<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_f32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_u8<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_f64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_f32<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_bool<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_f64<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
fn deserialize_usize<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
fn deserialize_bool<__V>(self, visitor: __V) -> Result<__V::Value, Self::Error>
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_isize<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
where __V: de::Visitor {
|
||||||
self.deserialize(visitor)
|
self.deserialize(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.next() {
|
match self.tokens.next() {
|
||||||
Some(Token::Bool(v)) => visitor.visit_bool(v),
|
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::I8(v)) => visitor.visit_i8(v),
|
||||||
Some(Token::I16(v)) => visitor.visit_i16(v),
|
Some(Token::I16(v)) => visitor.visit_i16(v),
|
||||||
Some(Token::I32(v)) => visitor.visit_i32(v),
|
Some(Token::I32(v)) => visitor.visit_i32(v),
|
||||||
Some(Token::I64(v)) => visitor.visit_i64(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::U8(v)) => visitor.visit_u8(v),
|
||||||
Some(Token::U16(v)) => visitor.visit_u16(v),
|
Some(Token::U16(v)) => visitor.visit_u16(v),
|
||||||
Some(Token::U32(v)) => visitor.visit_u32(v),
|
Some(Token::U32(v)) => visitor.visit_u32(v),
|
||||||
@@ -220,10 +245,11 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
Some(Token::Str(v)) => visitor.visit_str(v),
|
Some(Token::Str(v)) => visitor.visit_str(v),
|
||||||
Some(Token::String(v)) => visitor.visit_string(v),
|
Some(Token::String(v)) => visitor.visit_string(v),
|
||||||
Some(Token::Bytes(v)) => visitor.visit_bytes(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(false)) => visitor.visit_none(),
|
||||||
Some(Token::Option(true)) => visitor.visit_some(self),
|
Some(Token::Option(true)) => visitor.visit_some(self),
|
||||||
Some(Token::Unit) => visitor.visit_unit(),
|
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)) => {
|
Some(Token::SeqStart(len)) => {
|
||||||
self.visit_seq(len, visitor)
|
self.visit_seq(len, visitor)
|
||||||
}
|
}
|
||||||
@@ -237,13 +263,13 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
self.visit_map(Some(len), visitor)
|
self.visit_map(Some(len), visitor)
|
||||||
}
|
}
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
Some(token) => Err(Error::UnexpectedToken(token)),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hook into `Option` deserializing so we can treat `Unit` as a
|
/// Hook into `Option` deserializing so we can treat `Unit` as a
|
||||||
/// `None`, or a regular value as `Some(value)`.
|
/// `None`, or a regular value as `Some(value)`.
|
||||||
fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
@@ -260,21 +286,21 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
visitor.visit_none()
|
visitor.visit_none()
|
||||||
}
|
}
|
||||||
Some(_) => visitor.visit_some(self),
|
Some(_) => visitor.visit_some(self),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_enum<V>(&mut self,
|
fn deserialize_enum<V>(self,
|
||||||
name: &str,
|
name: &str,
|
||||||
_variants: &'static [&'static str],
|
_variants: &'static [&'static str],
|
||||||
mut visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: EnumVisitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
Some(&Token::EnumStart(n)) if name == n => {
|
Some(&Token::EnumStart(n)) if name == n => {
|
||||||
self.tokens.next();
|
self.tokens.next();
|
||||||
|
|
||||||
visitor.visit(DeserializerVariantVisitor {
|
visitor.visit_enum(DeserializerEnumVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -282,7 +308,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
| Some(&Token::EnumNewType(n, _))
|
| Some(&Token::EnumNewType(n, _))
|
||||||
| Some(&Token::EnumSeqStart(n, _, _))
|
| Some(&Token::EnumSeqStart(n, _, _))
|
||||||
| Some(&Token::EnumMapStart(n, _, _)) if name == n => {
|
| Some(&Token::EnumMapStart(n, _, _)) if name == n => {
|
||||||
visitor.visit(DeserializerVariantVisitor {
|
visitor.visit_enum(DeserializerEnumVisitor {
|
||||||
de: self,
|
de: self,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -290,11 +316,11 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
let token = self.tokens.next().unwrap();
|
let token = self.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => { return Err(Error::EndOfStream); }
|
None => { return Err(Error::EndOfTokens); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
|
fn deserialize_unit_struct<V>(self, name: &str, visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
@@ -307,13 +333,13 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_newtype_struct<V>(&mut self,
|
fn deserialize_newtype_struct<V>(self,
|
||||||
name: &str,
|
name: &str,
|
||||||
mut visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
@@ -326,11 +352,11 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq_fixed_size<V>(&mut self,
|
fn deserialize_seq_fixed_size<V>(self,
|
||||||
len: usize,
|
len: usize,
|
||||||
visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -341,13 +367,13 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
self.visit_array(len, visitor)
|
self.visit_array(len, visitor)
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_tuple<V>(&mut self,
|
fn deserialize_tuple<V>(self,
|
||||||
len: usize,
|
len: usize,
|
||||||
mut visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
@@ -376,14 +402,14 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
self.visit_tuple_struct(len, visitor)
|
self.visit_tuple_struct(len, visitor)
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_tuple_struct<V>(&mut self,
|
fn deserialize_tuple_struct<V>(self,
|
||||||
name: &str,
|
name: &str,
|
||||||
len: usize,
|
len: usize,
|
||||||
mut visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
{
|
{
|
||||||
match self.tokens.peek() {
|
match self.tokens.peek() {
|
||||||
@@ -420,11 +446,11 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_struct<V>(&mut self,
|
fn deserialize_struct<V>(self,
|
||||||
name: &str,
|
name: &str,
|
||||||
fields: &'static [&'static str],
|
fields: &'static [&'static str],
|
||||||
visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
@@ -434,7 +460,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
Some(&Token::StructStart(n, _)) => {
|
Some(&Token::StructStart(n, _)) => {
|
||||||
self.tokens.next();
|
self.tokens.next();
|
||||||
if name == n {
|
if name == n {
|
||||||
self.visit_struct(Some(fields.len()), visitor)
|
self.visit_struct(fields, visitor)
|
||||||
} else {
|
} else {
|
||||||
Err(Error::InvalidName(n))
|
Err(Error::InvalidName(n))
|
||||||
}
|
}
|
||||||
@@ -444,7 +470,7 @@ impl<I> de::Deserializer for Deserializer<I>
|
|||||||
self.visit_map(Some(fields.len()), visitor)
|
self.visit_map(Some(fields.len()), visitor)
|
||||||
}
|
}
|
||||||
Some(_) => self.deserialize(visitor),
|
Some(_) => self.deserialize(visitor),
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -461,30 +487,21 @@ impl<'a, I> SeqVisitor for DeserializerSeqVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::SeqSep) => {
|
Some(&Token::SeqSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len = self.len.map(|len| len - 1);
|
self.len = self.len.map(|len| len - 1);
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::SeqEnd) => Ok(None),
|
Some(&Token::SeqEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::SeqEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,30 +523,21 @@ impl<'a, I> SeqVisitor for DeserializerArrayVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::SeqSep) => {
|
Some(&Token::SeqSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len -= 1;
|
self.len -= 1;
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::SeqEnd) => Ok(None),
|
Some(&Token::SeqEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.len, 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::SeqEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,30 +558,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::TupleSep) => {
|
Some(&Token::TupleSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len -= 1;
|
self.len -= 1;
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::TupleEnd) => Ok(None),
|
Some(&Token::TupleEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.len, 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::TupleEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,30 +593,21 @@ impl<'a, I> SeqVisitor for DeserializerTupleStructVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::TupleStructSep) => {
|
Some(&Token::TupleStructSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len -= 1;
|
self.len -= 1;
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::TupleStructEnd) => Ok(None),
|
Some(&Token::TupleStructEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.len, 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::TupleStructEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,30 +628,21 @@ impl<'a, I> SeqVisitor for DeserializerVariantSeqVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::EnumSeqSep) => {
|
Some(&Token::EnumSeqSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len = self.len.map(|len| len - 1);
|
self.len = self.len.map(|len| len - 1);
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::EnumSeqEnd) => Ok(None),
|
Some(&Token::EnumSeqEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::EnumSeqEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,37 +664,28 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||||
where K: Deserialize,
|
where K: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::MapSep) => {
|
Some(&Token::MapSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::MapEnd) => Ok(None),
|
Some(&Token::MapEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||||
where V: Deserialize,
|
where V: DeserializeSeed,
|
||||||
{
|
{
|
||||||
Ok(try!(Deserialize::deserialize(self.de)))
|
seed.deserialize(&mut *self.de)
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::MapEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
@@ -726,7 +698,7 @@ impl<'a, I> MapVisitor for DeserializerMapVisitor<'a, I>
|
|||||||
|
|
||||||
struct DeserializerStructVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
struct DeserializerStructVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||||
de: &'a mut Deserializer<I>,
|
de: &'a mut Deserializer<I>,
|
||||||
len: Option<usize>,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
|
impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
|
||||||
@@ -734,76 +706,74 @@ impl<'a, I> MapVisitor for DeserializerStructVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||||
where K: Deserialize,
|
where K: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::StructSep) => {
|
Some(&Token::StructSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
self.len = self.len.saturating_sub(1);
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::StructEnd) => Ok(None),
|
Some(&Token::StructEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||||
where V: Deserialize,
|
where V: DeserializeSeed,
|
||||||
{
|
{
|
||||||
Ok(try!(Deserialize::deserialize(self.de)))
|
seed.deserialize(&mut *self.de)
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::StructEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
let len = self.len.unwrap_or(0);
|
(self.len, Some(self.len))
|
||||||
(len, self.len)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
struct DeserializerVariantVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
struct DeserializerEnumVisitor<'a, I: 'a> where I: Iterator<Item=Token<'static>> {
|
||||||
de: &'a mut Deserializer<I>,
|
de: &'a mut Deserializer<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
|
impl<'a, I> EnumVisitor for DeserializerEnumVisitor<'a, I>
|
||||||
where I: Iterator<Item=Token<'static>>,
|
where I: Iterator<Item=Token<'static>>,
|
||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
type Variant = Self;
|
||||||
|
|
||||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error>
|
||||||
where V: Deserialize,
|
where V: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::EnumUnit(_, v))
|
Some(&Token::EnumUnit(_, v))
|
||||||
| Some(&Token::EnumNewType(_, v))
|
| Some(&Token::EnumNewType(_, v))
|
||||||
| Some(&Token::EnumSeqStart(_, v, _))
|
| Some(&Token::EnumSeqStart(_, v, _))
|
||||||
| Some(&Token::EnumMapStart(_, v, _)) => {
|
| Some(&Token::EnumMapStart(_, v, _)) => {
|
||||||
let mut de = de::value::ValueDeserializer::<Error>::into_deserializer(v);
|
let de = v.into_deserializer();
|
||||||
let value = try!(Deserialize::deserialize(&mut de));
|
let value = try!(seed.deserialize(de));
|
||||||
Ok(value)
|
Ok((value, self))
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
Deserialize::deserialize(self.de)
|
let value = try!(seed.deserialize(&mut *self.de));
|
||||||
|
Ok((value, self))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I>
|
||||||
|
where I: Iterator<Item=Token<'static>>
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn visit_unit(self) -> Result<(), Error> {
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::EnumUnit(_, _)) => {
|
Some(&Token::EnumUnit(_, _)) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
@@ -812,26 +782,26 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
|
|||||||
Some(_) => {
|
Some(_) => {
|
||||||
Deserialize::deserialize(self.de)
|
Deserialize::deserialize(self.de)
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_newtype<T>(&mut self) -> Result<T, Self::Error>
|
fn visit_newtype_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
|
||||||
where T: Deserialize,
|
where T: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::EnumNewType(_, _)) => {
|
Some(&Token::EnumNewType(_, _)) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
Deserialize::deserialize(self.de)
|
seed.deserialize(self.de)
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
Deserialize::deserialize(self.de)
|
seed.deserialize(self.de)
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_tuple<V>(&mut self,
|
fn visit_tuple<V>(self,
|
||||||
len: usize,
|
len: usize,
|
||||||
visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -856,13 +826,13 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
Deserialize::deserialize(self.de)
|
de::Deserializer::deserialize(self.de, visitor)
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_struct<V>(&mut self,
|
fn visit_struct<V>(self,
|
||||||
fields: &'static [&'static str],
|
fields: &'static [&'static str],
|
||||||
visitor: V) -> Result<V::Value, Error>
|
visitor: V) -> Result<V::Value, Error>
|
||||||
where V: Visitor,
|
where V: Visitor,
|
||||||
@@ -887,9 +857,9 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
Deserialize::deserialize(self.de)
|
de::Deserializer::deserialize(self.de, visitor)
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -906,37 +876,28 @@ impl<'a, I> MapVisitor for DeserializerVariantMapVisitor<'a, I>
|
|||||||
{
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
fn visit_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||||
where K: Deserialize,
|
where K: DeserializeSeed,
|
||||||
{
|
{
|
||||||
match self.de.tokens.peek() {
|
match self.de.tokens.peek() {
|
||||||
Some(&Token::EnumMapSep) => {
|
Some(&Token::EnumMapSep) => {
|
||||||
self.de.tokens.next();
|
self.de.tokens.next();
|
||||||
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
self.len = self.len.map(|len| if len > 0 { len - 1} else { 0 });
|
||||||
Ok(Some(try!(Deserialize::deserialize(self.de))))
|
seed.deserialize(&mut *self.de).map(Some)
|
||||||
}
|
}
|
||||||
Some(&Token::EnumMapEnd) => Ok(None),
|
Some(&Token::EnumMapEnd) => Ok(None),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let token = self.de.tokens.next().unwrap();
|
let token = self.de.tokens.next().unwrap();
|
||||||
Err(Error::UnexpectedToken(token))
|
Err(Error::UnexpectedToken(token))
|
||||||
}
|
}
|
||||||
None => Err(Error::EndOfStream),
|
None => Err(Error::EndOfTokens),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
fn visit_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||||
where V: Deserialize,
|
where V: DeserializeSeed,
|
||||||
{
|
{
|
||||||
Ok(try!(Deserialize::deserialize(self.de)))
|
seed.deserialize(&mut *self.de)
|
||||||
}
|
|
||||||
|
|
||||||
fn end(&mut self) -> Result<(), Error> {
|
|
||||||
//assert_eq!(self.len.unwrap_or(0), 0);
|
|
||||||
match self.de.tokens.next() {
|
|
||||||
Some(Token::EnumMapEnd) => Ok(()),
|
|
||||||
Some(token) => Err(Error::UnexpectedToken(token)),
|
|
||||||
None => Err(Error::EndOfStream),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
|||||||
+21
-60
@@ -1,4 +1,5 @@
|
|||||||
use std::{error, fmt};
|
use std::error;
|
||||||
|
use std::fmt::{self, Display};
|
||||||
|
|
||||||
use serde::{ser, de};
|
use serde::{ser, de};
|
||||||
|
|
||||||
@@ -6,82 +7,42 @@ use token::Token;
|
|||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
// Shared
|
Message(String),
|
||||||
Custom(String),
|
|
||||||
InvalidValue(String),
|
|
||||||
|
|
||||||
// De
|
|
||||||
EndOfStream,
|
|
||||||
InvalidType(de::Type),
|
|
||||||
InvalidLength(usize),
|
|
||||||
UnknownVariant(String),
|
|
||||||
UnknownField(String),
|
|
||||||
MissingField(&'static str),
|
|
||||||
DuplicateField(&'static str),
|
|
||||||
InvalidName(&'static str),
|
InvalidName(&'static str),
|
||||||
UnexpectedToken(Token<'static>),
|
UnexpectedToken(Token<'static>),
|
||||||
|
EndOfTokens,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ser::Error for Error {
|
impl ser::Error for Error {
|
||||||
fn custom<T: Into<String>>(msg: T) -> Error {
|
fn custom<T: Display>(msg: T) -> Error {
|
||||||
Error::Custom(msg.into())
|
Error::Message(msg.to_string())
|
||||||
}
|
|
||||||
|
|
||||||
fn invalid_value(msg: &str) -> Error {
|
|
||||||
Error::InvalidValue(msg.to_owned())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl de::Error for Error {
|
impl de::Error for Error {
|
||||||
fn custom<T: Into<String>>(msg: T) -> Error {
|
fn custom<T: Display>(msg: T) -> Error {
|
||||||
Error::Custom(msg.into())
|
Error::Message(msg.to_string())
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
formatter.write_str(format!("{:?}", self).as_ref())
|
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 {
|
impl error::Error for Error {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
"Serde Error"
|
match *self {
|
||||||
}
|
Error::Message(ref msg) => msg,
|
||||||
|
Error::InvalidName(_) => "invalid name",
|
||||||
fn cause(&self) -> Option<&error::Error> {
|
Error::UnexpectedToken(_) => "unexpected token",
|
||||||
None
|
Error::EndOfTokens => "end of tokens",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+208
-185
@@ -1,9 +1,6 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use serde::ser::{
|
use serde::{ser, Serialize};
|
||||||
self,
|
|
||||||
Serialize,
|
|
||||||
};
|
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
@@ -30,294 +27,320 @@ impl<'a, I> Serializer<'a, I>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> ser::Serializer for Serializer<'a, I>
|
impl<'s, 'a, I> ser::Serializer for &'s mut Serializer<'a, I>
|
||||||
where I: Iterator<Item=&'a Token<'a>>,
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
{
|
{
|
||||||
|
type Ok = ();
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type MapState = ();
|
|
||||||
type SeqState = ();
|
|
||||||
type TupleState = ();
|
|
||||||
type TupleStructState = ();
|
|
||||||
type TupleVariantState = ();
|
|
||||||
type StructState = ();
|
|
||||||
type StructVariantState = ();
|
|
||||||
|
|
||||||
fn serialize_unit(&mut self) -> Result<(), Error> {
|
type SerializeSeq = Self;
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Unit));
|
type SerializeTuple = Self;
|
||||||
Ok(())
|
type SerializeTupleStruct = Self;
|
||||||
}
|
type SerializeTupleVariant = Self;
|
||||||
|
type SerializeMap = Self;
|
||||||
|
type SerializeStruct = Self;
|
||||||
|
type SerializeStructVariant = Self;
|
||||||
|
|
||||||
fn serialize_newtype_variant<T>(&mut self,
|
fn serialize_bool(self, v: bool) -> Result<(), Error> {
|
||||||
name: &str,
|
|
||||||
_variant_index: usize,
|
|
||||||
variant: &str,
|
|
||||||
value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize,
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant)));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_unit_struct(&mut self, name: &str) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_unit_variant(&mut self,
|
|
||||||
name: &str,
|
|
||||||
_variant_index: usize,
|
|
||||||
variant: &str) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant)));
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_bool(&mut self, v: bool) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Bool(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::Bool(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_isize(&mut self, v: isize) -> Result<(), Error> {
|
fn serialize_i8(self, v: i8) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Isize(v)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i8(&mut self, v: i8) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::I8(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::I8(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_i16(&mut self, v: i16) -> Result<(), Error> {
|
fn serialize_i16(self, v: i16) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::I16(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::I16(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_i32(&mut self, v: i32) -> Result<(), Error> {
|
fn serialize_i32(self, v: i32) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::I32(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::I32(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_i64(&mut self, v: i64) -> Result<(), Error> {
|
fn serialize_i64(self, v: i64) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::I64(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::I64(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_usize(&mut self, v: usize) -> Result<(), Error> {
|
fn serialize_u8(self, v: u8) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Usize(v)));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u8(&mut self, v: u8) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::U8(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::U8(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_u16(&mut self, v: u16) -> Result<(), Error> {
|
fn serialize_u16(self, v: u16) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::U16(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::U16(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_u32(&mut self, v: u32) -> Result<(), Error> {
|
fn serialize_u32(self, v: u32) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::U32(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::U32(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_u64(&mut self, v: u64) -> Result<(), Error> {
|
fn serialize_u64(self, v: u64) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::U64(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::U64(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_f32(&mut self, v: f32) -> Result<(), Error> {
|
fn serialize_f32(self, v: f32) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::F32(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::F32(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_f64(&mut self, v: f64) -> Result<(), Error> {
|
fn serialize_f64(self, v: f64) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::F64(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::F64(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_char(&mut self, v: char) -> Result<(), Error> {
|
fn serialize_char(self, v: char) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Char(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::Char(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_str(&mut self, v: &str) -> Result<(), Error> {
|
fn serialize_str(self, v: &str) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Str(v)));
|
assert_eq!(self.tokens.next(), Some(&Token::Str(v)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_none(&mut self) -> Result<(), Error> {
|
fn serialize_bytes(self, value: &[u8]) -> Result<(), Self::Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Option(false)));
|
assert_eq!(self.tokens.next(), Some(&Token::Bytes(value)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_some<V>(&mut self, value: V) -> Result<(), Error>
|
fn serialize_unit(self) -> Result<(), Error> {
|
||||||
where V: Serialize,
|
assert_eq!(self.tokens.next(), Some(&Token::Unit));
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::Option(true)));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq<'b>(&'b mut self, len: Option<usize>) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len)));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
|
fn serialize_unit_struct(self, name: &str) -> Result<(), Error> {
|
||||||
where T: Serialize
|
assert_eq!(self.tokens.next(), Some(&Token::UnitStruct(name)));
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq_end(&mut self, _: ()) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::SeqEnd));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq_fixed_size(&mut self, len: usize) -> Result<(), Error>
|
fn serialize_unit_variant(self,
|
||||||
{
|
name: &str,
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len)));
|
_variant_index: usize,
|
||||||
|
variant: &str) -> Result<(), Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::EnumUnit(name, variant)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple(&mut self, len: usize) -> Result<(), Error>
|
fn serialize_newtype_struct<T: ?Sized>(self,
|
||||||
{
|
name: &'static str,
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len)));
|
value: &T) -> Result<(), Error>
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::TupleSep));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_end(&mut self, _: ()) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::TupleEnd));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_newtype_struct<T>(&mut self,
|
|
||||||
name: &'static str,
|
|
||||||
value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize,
|
where T: Serialize,
|
||||||
{
|
{
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name)));
|
assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name)));
|
||||||
value.serialize(self)
|
value.serialize(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct(&mut self, name: &'static str, len: usize) -> 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::TupleStructStart(name, len)));
|
assert_eq!(self.tokens.next(), Some(&Token::EnumNewType(name, variant)));
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_struct_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep));
|
|
||||||
value.serialize(self)
|
value.serialize(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct_end(&mut self, _: ()) -> Result<(), Error> {
|
fn serialize_none(self) -> Result<(), Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd));
|
assert_eq!(self.tokens.next(), Some(&Token::Option(false)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_variant(&mut self,
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len)));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_seq_fixed_size(self, len: usize) -> Result<Self, Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len)));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len)));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleStructStart(name, len)));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_tuple_variant(self,
|
||||||
name: &str,
|
name: &str,
|
||||||
_variant_index: usize,
|
_variant_index: usize,
|
||||||
variant: &str,
|
variant: &str,
|
||||||
len: usize) -> Result<(), Error>
|
len: usize) -> Result<Self, Error>
|
||||||
{
|
{
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len)));
|
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len)));
|
||||||
|
Ok(self)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_tuple_variant_elt<T>(&mut self, _: &mut (), value: T) -> Result<(), Error>
|
fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_variant_end(&mut self, _: ()) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map(&mut self, len: Option<usize>) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::MapStart(len)));
|
assert_eq!(self.tokens.next(), Some(&Token::MapStart(len)));
|
||||||
|
Ok(self)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map_key<T>(&mut self, _: &mut (), key: T) -> Result<(), Self::Error> where T: Serialize {
|
fn serialize_struct(self, name: &str, len: usize) -> Result<Self, Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::MapSep));
|
|
||||||
key.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map_value<T>(&mut self, _: &mut (), value: T) -> Result<(), Self::Error> where T: Serialize {
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map_end(&mut self, _: ()) -> Result<(), Self::Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::MapEnd));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct(&mut self, name: &str, len: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len)));
|
assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len)));
|
||||||
|
Ok(self)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct_elt<V>(&mut self, _: &mut (), key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
|
fn serialize_struct_variant(self,
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::StructSep));
|
|
||||||
try!(key.serialize(self));
|
|
||||||
value.serialize(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_end(&mut self, _: ()) -> Result<(), Self::Error> {
|
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::StructEnd));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_variant(&mut self,
|
|
||||||
name: &str,
|
name: &str,
|
||||||
_variant_index: usize,
|
_variant_index: usize,
|
||||||
variant: &str,
|
variant: &str,
|
||||||
len: usize) -> Result<(), Error>
|
len: usize) -> Result<Self, Error>
|
||||||
{
|
{
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len)));
|
assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len)));
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeSeq for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::SeqSep));
|
||||||
|
value.serialize(&mut **self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::SeqEnd));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), key: &'static str, value: V) -> Result<(), Self::Error> where V: Serialize {
|
impl<'s, 'a, I> ser::SerializeTuple for &'s mut Serializer<'a, I>
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep));
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
try!(key.serialize(self));
|
{
|
||||||
value.serialize(self)
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleSep));
|
||||||
|
value.serialize(&mut **self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct_variant_end(&mut self, _: ()) -> Result<(), Self::Error> {
|
fn end(self) -> Result<(), Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleEnd));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeTupleStruct for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep));
|
||||||
|
value.serialize(&mut **self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeTupleVariant for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||||
|
where T: Serialize
|
||||||
|
{
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep));
|
||||||
|
value.serialize(&mut **self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeMap for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
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: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
|
||||||
|
value.serialize(&mut **self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Self::Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::MapEnd));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeStruct for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Self::Error> {
|
||||||
|
assert_eq!(self.tokens.next(), Some(&Token::StructEnd));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, 'a, I> ser::SerializeStructVariant for &'s mut Serializer<'a, I>
|
||||||
|
where I: Iterator<Item=&'a Token<'a>>,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Self::Error> {
|
||||||
assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd));
|
assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> {
|
|
||||||
let mut state = try!(self.serialize_seq(Some(value.len())));
|
|
||||||
for c in value {
|
|
||||||
try!(self.serialize_seq_elt(&mut state, c));
|
|
||||||
}
|
|
||||||
self.serialize_seq_end(state)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum Token<'a> {
|
pub enum Token<'a> {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Isize(isize),
|
|
||||||
I8(i8),
|
I8(i8),
|
||||||
I16(i16),
|
I16(i16),
|
||||||
I32(i32),
|
I32(i32),
|
||||||
I64(i64),
|
I64(i64),
|
||||||
Usize(usize),
|
|
||||||
U8(u8),
|
U8(u8),
|
||||||
U16(u16),
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
@@ -17,6 +15,7 @@ pub enum Token<'a> {
|
|||||||
Str(&'a str),
|
Str(&'a str),
|
||||||
String(String),
|
String(String),
|
||||||
Bytes(&'a [u8]),
|
Bytes(&'a [u8]),
|
||||||
|
ByteBuf(Vec<u8>),
|
||||||
|
|
||||||
Option(bool),
|
Option(bool),
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_testing"
|
name = "serde_testing"
|
||||||
version = "0.8.16"
|
version = "0.0.0"
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
@@ -10,6 +10,7 @@ documentation = "https://docs.serde.rs/serde/"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["serialization"]
|
keywords = ["serialization"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
publish = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
unstable-testing = ["clippy", "serde/unstable-testing", "serde_codegen/unstable-testing"]
|
unstable-testing = ["clippy", "serde/unstable-testing", "serde_codegen/unstable-testing"]
|
||||||
@@ -19,12 +20,12 @@ serde_codegen = { path = "../serde_codegen", features = ["with-syntex"] }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
rustc-serialize = "^0.3.16"
|
rustc-serialize = "0.3.16"
|
||||||
serde = { path = "../serde" }
|
serde = { path = "../serde" }
|
||||||
serde_test = { path = "../serde_test" }
|
serde_test = { path = "../serde_test" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "0.*", optional = true }
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "test"
|
name = "test"
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||||
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
#![cfg_attr(feature = "clippy", plugin(clippy))]
|
||||||
|
|
||||||
|
#![cfg_attr(feature = "unstable-testing", feature(non_ascii_idents))]
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/test.rs"));
|
include!(concat!(env!("OUT_DIR"), "/test.rs"));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
extern crate serde;
|
extern crate serde;
|
||||||
|
extern crate serde_test;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ trait ShouldSkip: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trait SerializeWith: Sized {
|
trait SerializeWith: Sized {
|
||||||
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer;
|
where S: Serializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait DeserializeWith: Sized {
|
trait DeserializeWith: Sized {
|
||||||
fn deserialize_with<D>(de: &mut D) -> Result<Self, D::Error>
|
fn deserialize_with<D>(de: D) -> Result<Self, D::Error>
|
||||||
where D: Deserializer;
|
where D: Deserializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ impl ShouldSkip for i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SerializeWith for i32 {
|
impl SerializeWith for i32 {
|
||||||
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer
|
where S: Serializer
|
||||||
{
|
{
|
||||||
if *self == 123 {
|
if *self == 123 {
|
||||||
@@ -50,7 +50,7 @@ impl SerializeWith for i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DeserializeWith for i32 {
|
impl DeserializeWith for i32 {
|
||||||
fn deserialize_with<D>(de: &mut D) -> Result<Self, D::Error>
|
fn deserialize_with<D>(de: D) -> Result<Self, D::Error>
|
||||||
where D: Deserializer
|
where D: Deserializer
|
||||||
{
|
{
|
||||||
if try!(Deserialize::deserialize(de)) {
|
if try!(Deserialize::deserialize(de)) {
|
||||||
@@ -145,7 +145,7 @@ fn test_default_enum() {
|
|||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 },
|
&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::EnumMapSep,
|
||||||
Token::Str("a1"),
|
Token::Str("a1"),
|
||||||
@@ -174,7 +174,7 @@ fn test_default_enum() {
|
|||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 },
|
&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::EnumMapSep,
|
||||||
Token::Str("a1"),
|
Token::Str("a1"),
|
||||||
@@ -239,7 +239,7 @@ impl Default for NotDeserializeStruct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DeserializeWith for NotDeserializeStruct {
|
impl DeserializeWith for NotDeserializeStruct {
|
||||||
fn deserialize_with<D>(_: &mut D) -> Result<Self, D::Error>
|
fn deserialize_with<D>(_: D) -> Result<Self, D::Error>
|
||||||
where D: Deserializer
|
where D: Deserializer
|
||||||
{
|
{
|
||||||
panic!()
|
panic!()
|
||||||
@@ -343,7 +343,7 @@ fn test_ignore_unknown() {
|
|||||||
Token::StructSep,
|
Token::StructSep,
|
||||||
Token::Str("whoops"),
|
Token::Str("whoops"),
|
||||||
],
|
],
|
||||||
Error::UnknownField("whoops".to_owned())
|
Error::Message("unknown field `whoops`, expected `a1`".to_owned())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +642,7 @@ struct NotSerializeStruct(i8);
|
|||||||
enum NotSerializeEnum { Trouble }
|
enum NotSerializeEnum { Trouble }
|
||||||
|
|
||||||
impl SerializeWith for NotSerializeEnum {
|
impl SerializeWith for NotSerializeEnum {
|
||||||
fn serialize_with<S>(&self, ser: &mut S) -> Result<(), S::Error>
|
fn serialize_with<S>(&self, ser: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer
|
where S: Serializer
|
||||||
{
|
{
|
||||||
"trouble".serialize(ser)
|
"trouble".serialize(ser)
|
||||||
@@ -905,7 +905,7 @@ fn test_missing_renamed_field_struct() {
|
|||||||
|
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
Error::MissingField("a3"),
|
Error::Message("missing field `a3`".to_owned()),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
|
assert_de_tokens_error::<RenameStructSerializeDeserialize>(
|
||||||
@@ -918,7 +918,7 @@ fn test_missing_renamed_field_struct() {
|
|||||||
|
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
Error::MissingField("a5"),
|
Error::Message("missing field `a5`".to_owned()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -930,7 +930,7 @@ fn test_missing_renamed_field_enum() {
|
|||||||
|
|
||||||
Token::EnumMapEnd,
|
Token::EnumMapEnd,
|
||||||
],
|
],
|
||||||
Error::MissingField("b"),
|
Error::Message("missing field `b`".to_owned()),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
|
assert_de_tokens_error::<RenameEnumSerializeDeserialize<i8>>(
|
||||||
@@ -943,7 +943,7 @@ fn test_missing_renamed_field_enum() {
|
|||||||
|
|
||||||
Token::EnumMapEnd,
|
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::I32(1),
|
||||||
Token::EnumSeqEnd,
|
Token::EnumSeqEnd,
|
||||||
],
|
],
|
||||||
Error::InvalidLength(1),
|
Error::Message("invalid length 1, expected tuple of 3 elements".to_owned()),
|
||||||
);
|
);
|
||||||
assert_de_tokens_error::<InvalidLengthEnum>(
|
assert_de_tokens_error::<InvalidLengthEnum>(
|
||||||
&[
|
&[
|
||||||
@@ -971,6 +971,6 @@ fn test_invalid_length_enum() {
|
|||||||
Token::I32(1),
|
Token::I32(1),
|
||||||
Token::EnumSeqEnd,
|
Token::EnumSeqEnd,
|
||||||
],
|
],
|
||||||
Error::InvalidLength(1),
|
Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+46
-451
@@ -1,460 +1,55 @@
|
|||||||
use std::fmt;
|
|
||||||
use std::error;
|
|
||||||
|
|
||||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
|
||||||
use serde::bytes::{ByteBuf, Bytes};
|
use serde::bytes::{ByteBuf, Bytes};
|
||||||
use serde::ser;
|
use serde_test::{assert_tokens, assert_ser_tokens, assert_de_tokens, Token};
|
||||||
use serde::de;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
|
||||||
struct Error;
|
|
||||||
|
|
||||||
impl ser::Error for Error {
|
|
||||||
fn custom<T: Into<String>>(_: T) -> Error { Error }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl de::Error for Error {
|
|
||||||
fn custom<T: Into<String>>(_: T) -> Error { Error }
|
|
||||||
|
|
||||||
fn end_of_stream() -> Error { Error }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
||||||
formatter.write_str(format!("{:?}", self).as_ref())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl error::Error for Error {
|
|
||||||
fn description(&self) -> &str {
|
|
||||||
"Serde Deserialization Error"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cause(&self) -> Option<&error::Error> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct BytesSerializer {
|
|
||||||
bytes: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BytesSerializer {
|
|
||||||
fn new(bytes: Vec<u8>) -> Self {
|
|
||||||
BytesSerializer {
|
|
||||||
bytes: bytes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serializer for BytesSerializer {
|
|
||||||
type Error = Error;
|
|
||||||
type SeqState = ();
|
|
||||||
type MapState = ();
|
|
||||||
type TupleState = ();
|
|
||||||
type TupleStructState = ();
|
|
||||||
type TupleVariantState = ();
|
|
||||||
type StructState = ();
|
|
||||||
type StructVariantState = ();
|
|
||||||
|
|
||||||
fn serialize_unit(&mut self) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_unit_struct(&mut self, _name: &'static str) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_unit_variant(&mut self, _: &'static str, _: usize, _: &'static str) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_bool(&mut self, _v: bool) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_isize(&mut self, _v: isize) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_usize(&mut self, _v: usize) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i8(&mut self, _v: i8) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u8(&mut self, _v: u8) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i16(&mut self, _v: i16) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u16(&mut self, _v: u16) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i32(&mut self, _v: i32) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u32(&mut self, _v: u32) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_i64(&mut self, _v: i64) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_u64(&mut self, _v: u64) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_f32(&mut self, _v: f32) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_f64(&mut self, _v: f64) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_char(&mut self, _v: char) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_str(&mut self, _v: &str) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_none(&mut self) -> Result<(), Error> {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_some<V>(&mut self, _value: V) -> Result<(), Error>
|
|
||||||
where V: Serialize,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_newtype_struct<V>(&mut self, _: &'static str, _value: V) -> Result<(), Error>
|
|
||||||
where V: Serialize,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_newtype_variant<V>(&mut self, _: &'static str, _: usize, _: &'static str, _value: V) -> Result<(), Error>
|
|
||||||
where V: Serialize,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq(&mut self, _len: Option<usize>) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq_fixed_size(&mut self, _len: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_seq_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple(&mut self, _len: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_struct(&mut self, _: &'static str, _len: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_struct_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_struct_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_variant(&mut self, _: &'static str, _: usize, _: &'static str, _len: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_variant_elt<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_tuple_variant_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map(&mut self, _: Option<usize>) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map_key<T>(&mut self, _: &mut (), _key: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map_value<T>(&mut self, _: &mut (), _value: T) -> Result<(), Error>
|
|
||||||
where T: Serialize
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_map_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct(&mut self, _: &'static str, _: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_elt<V>(&mut self, _: &mut (), _key: &'static str, _value: V) -> Result<(), Error>
|
|
||||||
where V: Serialize,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_variant(&mut self, _: &'static str, _: usize, _: &'static str, _: usize) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_variant_elt<V>(&mut self, _: &mut (), _key: &'static str, _value: V) -> Result<(), Error>
|
|
||||||
where V: Serialize,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_struct_variant_end(&mut self, _: ()) -> Result<(), Error>
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn serialize_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> {
|
|
||||||
assert_eq!(self.bytes, bytes);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
struct BytesDeserializer {
|
|
||||||
bytes: Option<Vec<u8>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BytesDeserializer {
|
|
||||||
fn new(bytes: Vec<u8>) -> Self {
|
|
||||||
BytesDeserializer {
|
|
||||||
bytes: Some(bytes),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Deserializer for BytesDeserializer {
|
|
||||||
type Error = Error;
|
|
||||||
|
|
||||||
fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_bytes<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
|
||||||
where V: de::Visitor,
|
|
||||||
{
|
|
||||||
visitor.visit_byte_buf(self.bytes.take().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_seq<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_struct_field<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_map<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_unit<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_ignored_any<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_string<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_str<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_char<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_i64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_i32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_i16<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_i8<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_u64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_u32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_u16<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_u8<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_f32<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_f64<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_bool<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_usize<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_isize<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
|
|
||||||
where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_option<__V>(&mut self, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_seq_fixed_size<__V>(&mut self, _: usize, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_unit_struct<__V>(&mut self, _: &str, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_newtype_struct<__V>(&mut self, _: &str, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_tuple_struct<__V>(&mut self, _: &str, _: usize, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_struct<__V>(&mut self, _: &str, _: &[&str], visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_tuple<__V>(&mut self, _: usize, visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::Visitor {
|
|
||||||
self.deserialize(visitor)
|
|
||||||
}
|
|
||||||
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _visitor: __V)
|
|
||||||
-> Result<__V::Value, Self::Error> where __V: de::EnumVisitor {
|
|
||||||
Err(Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bytes_ser_bytes() {
|
fn test_bytes() {
|
||||||
let buf = vec![];
|
let empty = Bytes::new(&[]);
|
||||||
let bytes = Bytes::from(&buf);
|
assert_ser_tokens(&empty, &[Token::Bytes(b"")]);
|
||||||
let mut ser = BytesSerializer::new(vec![]);
|
|
||||||
bytes.serialize(&mut ser).unwrap();
|
|
||||||
|
|
||||||
let buf = vec![1, 2, 3];
|
let buf = vec![65, 66, 67];
|
||||||
let bytes = Bytes::from(&buf);
|
let bytes = Bytes::new(&buf);
|
||||||
let mut ser = BytesSerializer::new(vec![1, 2, 3]);
|
assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]);
|
||||||
bytes.serialize(&mut ser).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_byte_buf_de_bytes() {
|
fn test_byte_buf() {
|
||||||
let mut de = BytesDeserializer::new(vec![]);
|
let empty = ByteBuf::new();
|
||||||
let bytes = Deserialize::deserialize(&mut de);
|
assert_tokens(&empty, &[Token::Bytes(b"")]);
|
||||||
assert_eq!(bytes, Ok(ByteBuf::new()));
|
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, &[
|
||||||
|
Token::SeqStart(None),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
assert_de_tokens(&empty, &[
|
||||||
|
Token::SeqStart(Some(0)),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
|
||||||
let mut de = BytesDeserializer::new(vec![1, 2, 3]);
|
let buf = ByteBuf::from(vec![65, 66, 67]);
|
||||||
let bytes = Deserialize::deserialize(&mut de);
|
assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
|
||||||
assert_eq!(bytes, Ok(ByteBuf::from(vec![1, 2, 3])));
|
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, &[
|
||||||
|
Token::SeqStart(None),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(65),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(66),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(67),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
assert_de_tokens(&buf, &[
|
||||||
|
Token::SeqStart(Some(3)),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(65),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(66),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::U8(67),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
+110
-9
@@ -32,12 +32,43 @@ struct Struct {
|
|||||||
c: i32,
|
c: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct StructDenyUnknown {
|
||||||
|
a: i32,
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
struct StructSkipAll {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct StructSkipAllDenyUnknown {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
a: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Deserialize)]
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
enum Enum {
|
enum Enum {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Skipped,
|
||||||
Unit,
|
Unit,
|
||||||
Simple(i32),
|
Simple(i32),
|
||||||
Seq(i32, i32, i32),
|
Seq(i32, i32, i32),
|
||||||
Map { a: i32, b: i32, c: i32 }
|
Map { a: i32, b: i32, c: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
|
enum EnumSkipAll {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Skipped,
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -124,12 +155,10 @@ declare_tests! {
|
|||||||
false => &[Token::Bool(false)],
|
false => &[Token::Bool(false)],
|
||||||
}
|
}
|
||||||
test_isize {
|
test_isize {
|
||||||
0isize => &[Token::Isize(0)],
|
|
||||||
0isize => &[Token::I8(0)],
|
0isize => &[Token::I8(0)],
|
||||||
0isize => &[Token::I16(0)],
|
0isize => &[Token::I16(0)],
|
||||||
0isize => &[Token::I32(0)],
|
0isize => &[Token::I32(0)],
|
||||||
0isize => &[Token::I64(0)],
|
0isize => &[Token::I64(0)],
|
||||||
0isize => &[Token::Usize(0)],
|
|
||||||
0isize => &[Token::U8(0)],
|
0isize => &[Token::U8(0)],
|
||||||
0isize => &[Token::U16(0)],
|
0isize => &[Token::U16(0)],
|
||||||
0isize => &[Token::U32(0)],
|
0isize => &[Token::U32(0)],
|
||||||
@@ -138,14 +167,12 @@ declare_tests! {
|
|||||||
0isize => &[Token::F64(0.)],
|
0isize => &[Token::F64(0.)],
|
||||||
}
|
}
|
||||||
test_ints {
|
test_ints {
|
||||||
0isize => &[Token::Isize(0)],
|
|
||||||
0i8 => &[Token::I8(0)],
|
0i8 => &[Token::I8(0)],
|
||||||
0i16 => &[Token::I16(0)],
|
0i16 => &[Token::I16(0)],
|
||||||
0i32 => &[Token::I32(0)],
|
0i32 => &[Token::I32(0)],
|
||||||
0i64 => &[Token::I64(0)],
|
0i64 => &[Token::I64(0)],
|
||||||
}
|
}
|
||||||
test_uints {
|
test_uints {
|
||||||
0usize => &[Token::Usize(0)],
|
|
||||||
0u8 => &[Token::U8(0)],
|
0u8 => &[Token::U8(0)],
|
||||||
0u16 => &[Token::U16(0)],
|
0u16 => &[Token::U16(0)],
|
||||||
0u32 => &[Token::U32(0)],
|
0u32 => &[Token::U32(0)],
|
||||||
@@ -215,6 +242,9 @@ declare_tests! {
|
|||||||
Token::SeqEnd,
|
Token::SeqEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_unit_string {
|
||||||
|
String::new() => &[Token::Unit],
|
||||||
|
}
|
||||||
test_tuple_struct {
|
test_tuple_struct {
|
||||||
TupleStruct(1, 2, 3) => &[
|
TupleStruct(1, 2, 3) => &[
|
||||||
Token::SeqStart(Some(3)),
|
Token::SeqStart(Some(3)),
|
||||||
@@ -675,6 +705,29 @@ declare_tests! {
|
|||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_struct_skip_all {
|
||||||
|
StructSkipAll { a: 0 } => &[
|
||||||
|
Token::StructStart("StructSkipAll", 0),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
StructSkipAll { a: 0 } => &[
|
||||||
|
Token::StructStart("StructSkipAll", 1),
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(1),
|
||||||
|
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(2),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_struct_skip_all_deny_unknown {
|
||||||
|
StructSkipAllDenyUnknown { a: 0 } => &[
|
||||||
|
Token::StructStart("StructSkipAllDenyUnknown", 0),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_enum_unit {
|
test_enum_unit {
|
||||||
Enum::Unit => &[
|
Enum::Unit => &[
|
||||||
Token::EnumUnit("Enum", "Unit"),
|
Token::EnumUnit("Enum", "Unit"),
|
||||||
@@ -720,7 +773,7 @@ declare_tests! {
|
|||||||
test_enum_unit_usize {
|
test_enum_unit_usize {
|
||||||
Enum::Unit => &[
|
Enum::Unit => &[
|
||||||
Token::EnumStart("Enum"),
|
Token::EnumStart("Enum"),
|
||||||
Token::Usize(0),
|
Token::U32(0),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -796,11 +849,51 @@ fn test_net_ipaddr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare_error_tests! {
|
declare_error_tests! {
|
||||||
|
test_unknown_field<StructDenyUnknown> {
|
||||||
|
&[
|
||||||
|
Token::StructStart("StructDenyUnknown", 2),
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("d"),
|
||||||
|
],
|
||||||
|
Error::Message("unknown field `d`, expected `a`".to_owned()),
|
||||||
|
}
|
||||||
|
test_skipped_field_is_unknown<StructDenyUnknown> {
|
||||||
|
&[
|
||||||
|
Token::StructStart("StructDenyUnknown", 2),
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("b"),
|
||||||
|
],
|
||||||
|
Error::Message("unknown field `b`, expected `a`".to_owned()),
|
||||||
|
}
|
||||||
|
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
|
||||||
|
&[
|
||||||
|
Token::StructStart("StructSkipAllDenyUnknown", 1),
|
||||||
|
Token::StructSep,
|
||||||
|
Token::Str("a"),
|
||||||
|
],
|
||||||
|
Error::Message("unknown field `a`, there are no fields".to_owned()),
|
||||||
|
}
|
||||||
test_unknown_variant<Enum> {
|
test_unknown_variant<Enum> {
|
||||||
&[
|
&[
|
||||||
Token::EnumUnit("Enum", "Foo"),
|
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::Message("unknown variant `Skipped`, expected one of `Unit`, `Simple`, `Seq`, `Map`".to_owned()),
|
||||||
|
}
|
||||||
|
test_enum_skip_all<EnumSkipAll> {
|
||||||
|
&[
|
||||||
|
Token::EnumUnit("EnumSkipAll", "Skipped"),
|
||||||
|
],
|
||||||
|
Error::Message("unknown variant `Skipped`, there are no variants".to_owned()),
|
||||||
}
|
}
|
||||||
test_struct_seq_too_long<Struct> {
|
test_struct_seq_too_long<Struct> {
|
||||||
&[
|
&[
|
||||||
@@ -821,7 +914,7 @@ declare_error_tests! {
|
|||||||
Token::MapSep,
|
Token::MapSep,
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
],
|
],
|
||||||
Error::DuplicateField("a"),
|
Error::Message("duplicate field `a`".to_owned()),
|
||||||
}
|
}
|
||||||
test_duplicate_field_enum<Enum> {
|
test_duplicate_field_enum<Enum> {
|
||||||
&[
|
&[
|
||||||
@@ -833,6 +926,14 @@ declare_error_tests! {
|
|||||||
Token::EnumMapSep,
|
Token::EnumMapSep,
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
],
|
],
|
||||||
Error::DuplicateField("a"),
|
Error::Message("duplicate field `a`".to_owned()),
|
||||||
|
}
|
||||||
|
test_enum_out_of_range<Enum> {
|
||||||
|
&[
|
||||||
|
Token::EnumStart("Enum"),
|
||||||
|
Token::U32(4),
|
||||||
|
Token::Unit,
|
||||||
|
],
|
||||||
|
Error::Message("invalid value: integer `4`, expected variant index 0 <= i < 4".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,6 +202,91 @@ fn test_gen() {
|
|||||||
EmptyStruct {},
|
EmptyStruct {},
|
||||||
}
|
}
|
||||||
assert::<EmptyEnumVariant>();
|
assert::<EmptyEnumVariant>();
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
struct NonAsciiIdents {
|
||||||
|
σ: f64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct EmptyBraced {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct EmptyBracedDenyUnknown {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct BracedSkipAll {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct BracedSkipAllDenyUnknown {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
struct EmptyTuple();
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct EmptyTupleDenyUnknown();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum EmptyEnum {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
enum EmptyEnumDenyUnknown {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum EnumSkipAll {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Variant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
enum EmptyVariants {
|
||||||
|
Braced {},
|
||||||
|
Tuple(),
|
||||||
|
BracedSkip {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
},
|
||||||
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
enum EmptyVariantsDenyUnknown {
|
||||||
|
Braced {},
|
||||||
|
Tuple(),
|
||||||
|
BracedSkip {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
},
|
||||||
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct UnitDenyUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -210,32 +295,32 @@ fn assert<T: Serialize + Deserialize>() {}
|
|||||||
fn assert_ser<T: Serialize>() {}
|
fn assert_ser<T: Serialize>() {}
|
||||||
|
|
||||||
trait SerializeWith {
|
trait SerializeWith {
|
||||||
fn serialize_with<S: Serializer>(_: &Self, _: &mut S) -> StdResult<(), S::Error>;
|
fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait DeserializeWith: Sized {
|
trait DeserializeWith: Sized {
|
||||||
fn deserialize_with<D: Deserializer>(_: &mut D) -> StdResult<Self, D::Error>;
|
fn deserialize_with<D: Deserializer>(_: D) -> StdResult<Self, D::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements neither Serialize nor Deserialize
|
// Implements neither Serialize nor Deserialize
|
||||||
struct X;
|
struct X;
|
||||||
|
|
||||||
fn ser_x<S: Serializer>(_: &X, _: &mut S) -> StdResult<(), S::Error> {
|
fn ser_x<S: Serializer>(_: &X, _: S) -> StdResult<S::Ok, S::Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn de_x<D: Deserializer>(_: &mut D) -> StdResult<X, D::Error> {
|
fn de_x<D: Deserializer>(_: D) -> StdResult<X, D::Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializeWith for X {
|
impl SerializeWith for X {
|
||||||
fn serialize_with<S: Serializer>(_: &Self, _: &mut S) -> StdResult<(), S::Error> {
|
fn serialize_with<S: Serializer>(_: &Self, _: S) -> StdResult<S::Ok, S::Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeserializeWith for X {
|
impl DeserializeWith for X {
|
||||||
fn deserialize_with<D: Deserializer>(_: &mut D) -> StdResult<Self, D::Error> {
|
fn deserialize_with<D: Deserializer>(_: D) -> StdResult<Self, D::Error> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ use self::serde_test::{
|
|||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
use self::fnv::FnvHasher;
|
use self::fnv::FnvHasher;
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
use serde::ser::iterator;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@@ -30,12 +33,20 @@ struct Struct {
|
|||||||
c: i32,
|
c: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize, PartialEq, Debug)]
|
||||||
enum Enum {
|
enum Enum {
|
||||||
Unit,
|
Unit,
|
||||||
One(i32),
|
One(i32),
|
||||||
Seq(i32, i32),
|
Seq(i32, i32),
|
||||||
Map { a: i32, b: i32 },
|
Map { a: i32, b: i32 },
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedUnit,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedOne(i32),
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedSeq(i32, i32),
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedMap { _a: i32, _b: i32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -49,14 +60,12 @@ declare_ser_tests! {
|
|||||||
false => &[Token::Bool(false)],
|
false => &[Token::Bool(false)],
|
||||||
}
|
}
|
||||||
test_isizes {
|
test_isizes {
|
||||||
0isize => &[Token::Isize(0)],
|
|
||||||
0i8 => &[Token::I8(0)],
|
0i8 => &[Token::I8(0)],
|
||||||
0i16 => &[Token::I16(0)],
|
0i16 => &[Token::I16(0)],
|
||||||
0i32 => &[Token::I32(0)],
|
0i32 => &[Token::I32(0)],
|
||||||
0i64 => &[Token::I64(0)],
|
0i64 => &[Token::I64(0)],
|
||||||
}
|
}
|
||||||
test_usizes {
|
test_usizes {
|
||||||
0usize => &[Token::Usize(0)],
|
|
||||||
0u8 => &[Token::U8(0)],
|
0u8 => &[Token::U8(0)],
|
||||||
0u16 => &[Token::U16(0)],
|
0u16 => &[Token::U16(0)],
|
||||||
0u32 => &[Token::U32(0)],
|
0u32 => &[Token::U32(0)],
|
||||||
@@ -361,6 +370,49 @@ declare_ser_tests! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable")]
|
||||||
|
#[test]
|
||||||
|
fn test_iterator() {
|
||||||
|
assert_ser_tokens(iterator([0; 0].iter()), &[
|
||||||
|
Token::SeqStart(Some(0)),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
assert_ser_tokens(iterator([1, 2, 3].iter()), &[
|
||||||
|
Token::SeqStart(Some(3)),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(1),
|
||||||
|
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(2),
|
||||||
|
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(3),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
assert_ser_tokens(iterator([1, 2, 3].iter().map(|x| x * 2)), &[
|
||||||
|
Token::SeqStart(Some(3)),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(2),
|
||||||
|
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(4),
|
||||||
|
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(6),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
assert_ser_tokens(iterator([1, 2, 3].iter().filter(|&x| x % 2 != 0)), &[
|
||||||
|
Token::SeqStart(None),
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(1),
|
||||||
|
|
||||||
|
Token::SeqSep,
|
||||||
|
Token::I32(3),
|
||||||
|
Token::SeqEnd,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_net_ipaddr() {
|
fn test_net_ipaddr() {
|
||||||
@@ -378,7 +430,7 @@ fn test_cannot_serialize_paths() {
|
|||||||
assert_ser_tokens_error(
|
assert_ser_tokens_error(
|
||||||
&Path::new(path),
|
&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();
|
let mut path_buf = PathBuf::new();
|
||||||
path_buf.push(path);
|
path_buf.push(path);
|
||||||
@@ -386,5 +438,25 @@ fn test_cannot_serialize_paths() {
|
|||||||
assert_ser_tokens_error(
|
assert_ser_tokens_error(
|
||||||
&path_buf,
|
&path_buf,
|
||||||
&[],
|
&[],
|
||||||
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
|
Error::Message("path contains invalid UTF-8 characters".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enum_skipped() {
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedUnit,
|
||||||
|
&[],
|
||||||
|
Error::Message("the enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedOne(42),
|
||||||
|
&[],
|
||||||
|
Error::Message("the enum variant Enum::SkippedOne cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedSeq(1, 2),
|
||||||
|
&[],
|
||||||
|
Error::Message("the enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedMap { _a: 1, _b: 2 },
|
||||||
|
&[],
|
||||||
|
Error::Message("the enum variant Enum::SkippedMap cannot be serialized".to_owned()));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user