mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 18:07:57 +00:00
Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b4803115b | |||
| fa5f0f4541 | |||
| 4b7f55bd42 | |||
| 593bcb087d | |||
| f58000cb41 | |||
| 01b86d5ce4 | |||
| c80f9238d7 | |||
| 62850bf832 | |||
| 9f114548f4 | |||
| 8890061f82 | |||
| 2c05518810 | |||
| 4aeb0df88f | |||
| 6550231a51 | |||
| ea0012fc5a | |||
| d6b62b9417 | |||
| 2ee347c5a5 | |||
| 4305260174 | |||
| 35aae92b56 | |||
| f3f26796c7 | |||
| d1460e1f0d | |||
| dfd81323d5 | |||
| 368961e961 | |||
| f9c6f0ab62 | |||
| b2b36e1764 | |||
| 4ad140ea70 | |||
| 67777eb585 | |||
| b4e51fcc77 | |||
| be7fe2a5eb | |||
| b4076f4577 | |||
| c4181f46be | |||
| 8c0efc3d77 | |||
| 7e3efaf6c5 | |||
| 12fe42ed45 | |||
| 7cd4f49c76 | |||
| ff9c85d47f | |||
| 0025ef9aba | |||
| 536bdd77a0 | |||
| 6993b983d2 | |||
| 4bfeb05f22 | |||
| 4687c1b52b | |||
| a58abae193 | |||
| 0bc9c729b3 | |||
| dc921892be | |||
| 62557731c3 | |||
| ab62cd3b28 | |||
| 30824e9f61 | |||
| eecc0870fc | |||
| 6475e73b05 | |||
| 697234517d | |||
| 3cd9d071c2 | |||
| 9dc05c36f0 | |||
| 972cc06fed | |||
| 20013464f8 | |||
| 2009b4da5f | |||
| 0b72c86a35 | |||
| 94b857057b | |||
| 979df3427b | |||
| 978d64993e | |||
| 5098609935 | |||
| 6374467f02 | |||
| 1f9fc61b98 | |||
| 3859f58d9b | |||
| aac1c65033 | |||
| d8120e19bc | |||
| ed425b3a6f | |||
| d1297deb36 | |||
| f263e3fcec | |||
| 40479336c1 | |||
| 6ca4dd2c4a | |||
| c04c233838 | |||
| 175c638fdc | |||
| 97eff8e875 | |||
| 47676cdb49 | |||
| 93bddb361e | |||
| adb1c9540d | |||
| 0e1d065402 | |||
| 8c3b52e308 | |||
| 3f0d3453d8 | |||
| b27a27ce22 | |||
| 80c0600657 | |||
| 77f9e63661 | |||
| b78f434086 | |||
| 893c0578dd | |||
| cb2b92f828 | |||
| 47a4ffbd31 | |||
| d82d1707d6 | |||
| 89278996c5 | |||
| ecef937e26 | |||
| bceda5fb18 | |||
| f46a08b04e | |||
| f3cb7c7a32 | |||
| af795e2e54 | |||
| 6aa07fe0d6 | |||
| c455720f81 | |||
| b07a208716 | |||
| df93fab5fa | |||
| 1a972d2105 | |||
| 6d1807bb4a | |||
| b37cf858ce | |||
| 5f8fa33756 | |||
| f3f006f411 | |||
| 607966dcf7 | |||
| 6a8c39b2aa | |||
| 382f3c2771 | |||
| 85ca12a8c3 |
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Problem
|
||||||
|
about: Something does not seem right
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Share how Serde could support your use case better
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Documentation
|
||||||
|
about: Certainly there is room for improvement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Help or discussion
|
||||||
|
about: This is the right place
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
name: Anything else!
|
||||||
|
about: Whatever is on your mind
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@ cache: cargo
|
|||||||
# run builds for all the trains (and more)
|
# run builds for all the trains (and more)
|
||||||
rust:
|
rust:
|
||||||
- 1.13.0
|
- 1.13.0
|
||||||
|
- 1.15.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
|||||||
+3
-7
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.40" # remember to update html_root_url
|
version = "1.0.57" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@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,7 +10,8 @@ documentation = "https://docs.serde.rs/serde/"
|
|||||||
keywords = ["serde", "serialization", "no_std"]
|
keywords = ["serde", "serialization", "no_std"]
|
||||||
categories = ["encoding"]
|
categories = ["encoding"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
travis-ci = { repository = "serde-rs/serde" }
|
travis-ci = { repository = "serde-rs/serde" }
|
||||||
@@ -61,8 +62,3 @@ alloc = ["unstable"]
|
|||||||
# does not preserve identity and may result in multiple copies of the same data.
|
# does not preserve identity and may result in multiple copies of the same data.
|
||||||
# Be sure that this is what you want before enabling this feature.
|
# Be sure that this is what you want before enabling this feature.
|
||||||
rc = []
|
rc = []
|
||||||
|
|
||||||
# Get serde_derive picked up by the Integer 32 playground. Not public API.
|
|
||||||
#
|
|
||||||
# http://play.integer32.com/
|
|
||||||
playground = ["serde_derive"]
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::str::{self, FromStr};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rustc = match env::var_os("RUSTC") {
|
||||||
|
Some(rustc) => rustc,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let output = match Command::new(rustc).arg("--version").output() {
|
||||||
|
Ok(output) => output,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let version = match str::from_utf8(&output.stdout) {
|
||||||
|
Ok(version) => version,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut pieces = version.split('.');
|
||||||
|
if pieces.next() != Some("rustc 1") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = match pieces.next() {
|
||||||
|
Some(next) => next,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let minor = match u32::from_str(next) {
|
||||||
|
Ok(minor) => minor,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 128-bit integers stabilized in Rust 1.26:
|
||||||
|
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
|
||||||
|
if minor >= 26 {
|
||||||
|
println!("cargo:rustc-cfg=integer128");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,8 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl<'de, T> Visitor<'de> for NthElement<T>
|
/// impl<'de, T> Visitor<'de> for NthElement<T>
|
||||||
/// where T: Deserialize<'de>
|
/// where
|
||||||
|
/// T: Deserialize<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// type Value = T;
|
/// type Value = T;
|
||||||
///
|
///
|
||||||
@@ -54,7 +55,8 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
/// where A: SeqAccess<'de>
|
/// where
|
||||||
|
/// A: SeqAccess<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // Skip over the first `n` elements.
|
/// // Skip over the first `n` elements.
|
||||||
/// for i in 0..self.n {
|
/// for i in 0..self.n {
|
||||||
@@ -82,19 +84,22 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
|
/// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
|
||||||
/// where T: Deserialize<'de>
|
/// where
|
||||||
|
/// T: Deserialize<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// type Value = T;
|
/// type Value = T;
|
||||||
///
|
///
|
||||||
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
/// where D: Deserializer<'de>
|
/// where
|
||||||
|
/// D: Deserializer<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// deserializer.deserialize_seq(self)
|
/// deserializer.deserialize_seq(self)
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
|
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
|
||||||
/// # where D: Deserializer<'de>
|
/// # where
|
||||||
|
/// # D: Deserializer<'de>,
|
||||||
/// # {
|
/// # {
|
||||||
/// // Deserialize only the sequence element at index 3 from this deserializer.
|
/// // Deserialize only the sequence element at index 3 from this deserializer.
|
||||||
/// // The element at index 3 is required to be a string. Elements before and
|
/// // The element at index 3 is required to be a string. Elements before and
|
||||||
|
|||||||
+118
-89
@@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
|
use de::{
|
||||||
Visitor};
|
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use de::MapAccess;
|
use de::MapAccess;
|
||||||
@@ -31,7 +32,7 @@ impl<'de> Visitor<'de> for UnitVisitor {
|
|||||||
formatter.write_str("unit")
|
formatter.write_str("unit")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_unit<E>(self) -> Result<(), E>
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -40,7 +41,7 @@ impl<'de> Visitor<'de> for UnitVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for () {
|
impl<'de> Deserialize<'de> for () {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<(), D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -59,7 +60,7 @@ impl<'de> Visitor<'de> for BoolVisitor {
|
|||||||
formatter.write_str("a boolean")
|
formatter.write_str("a boolean")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bool<E>(self, v: bool) -> Result<bool, E>
|
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -68,7 +69,7 @@ impl<'de> Visitor<'de> for BoolVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for bool {
|
impl<'de> Deserialize<'de> for bool {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<bool, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -109,7 +110,7 @@ macro_rules! impl_deserialize_num {
|
|||||||
($ty:ident, $method:ident, $($visit:ident),*) => {
|
($ty:ident, $method:ident, $($visit:ident),*) => {
|
||||||
impl<'de> Deserialize<'de> for $ty {
|
impl<'de> Deserialize<'de> for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -177,7 +178,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_char<E>(self, v: char) -> Result<char, E>
|
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -185,7 +186,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_str<E>(self, v: &str) -> Result<char, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -199,7 +200,7 @@ impl<'de> Visitor<'de> for CharVisitor {
|
|||||||
|
|
||||||
impl<'de> Deserialize<'de> for char {
|
impl<'de> Deserialize<'de> for char {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: D) -> Result<char, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -222,21 +223,21 @@ impl<'de> Visitor<'de> for StringVisitor {
|
|||||||
formatter.write_str("a string")
|
formatter.write_str("a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<String, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.to_owned())
|
Ok(v.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<String, E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<String, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -246,7 +247,7 @@ impl<'de> Visitor<'de> for StringVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<String, E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -268,7 +269,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
formatter.write_str("a string")
|
formatter.write_str("a string")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<(), E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -277,7 +278,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<(), E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -285,7 +286,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -299,7 +300,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -318,7 +319,7 @@ impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
|
|||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'de> Deserialize<'de> for String {
|
impl<'de> Deserialize<'de> for String {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -416,7 +417,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
|||||||
formatter.write_str("byte array")
|
formatter.write_str("byte array")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<CString, A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -430,28 +431,28 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
|||||||
CString::new(values).map_err(Error::custom)
|
CString::new(values).map_err(Error::custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<CString, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
CString::new(v).map_err(Error::custom)
|
CString::new(v).map_err(Error::custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<CString, E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
CString::new(v).map_err(Error::custom)
|
CString::new(v).map_err(Error::custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<CString, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
CString::new(v).map_err(Error::custom)
|
CString::new(v).map_err(Error::custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<CString, E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -461,7 +462,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'de> Deserialize<'de> for CString {
|
impl<'de> Deserialize<'de> for CString {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -506,7 +507,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_unit<E>(self) -> Result<Option<T>, E>
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -514,7 +515,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_none<E>(self) -> Result<Option<T>, E>
|
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -522,19 +523,27 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
|
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
T::deserialize(deserializer).map(Some)
|
T::deserialize(deserializer).map(Some)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn __private_visit_untagged_option<D>(self, deserializer: D) -> Result<Self::Value, ()>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(T::deserialize(deserializer).ok())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, T> Deserialize<'de> for Option<T>
|
impl<'de, T> Deserialize<'de> for Option<T>
|
||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -564,7 +573,7 @@ impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -573,7 +582,7 @@ impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
|
impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<PhantomData<T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -658,7 +667,7 @@ macro_rules! seq_impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
|
fn visit_seq<A>(mut self, mut $access: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -770,7 +779,7 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<A>(self, _: A) -> Result<[T; 0], A::Error>
|
fn visit_seq<A>(self, _: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -780,7 +789,7 @@ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
|
|||||||
|
|
||||||
// Does not require T: Deserialize<'de>.
|
// Does not require T: Deserialize<'de>.
|
||||||
impl<'de, T> Deserialize<'de> for [T; 0] {
|
impl<'de, T> Deserialize<'de> for [T; 0] {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<[T; 0], D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -802,7 +811,7 @@ macro_rules! array_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<[T; $len], A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -828,7 +837,7 @@ macro_rules! array_impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -850,7 +859,7 @@ macro_rules! array_impls {
|
|||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -910,7 +919,7 @@ macro_rules! tuple_impls {
|
|||||||
$(
|
$(
|
||||||
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
|
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -927,7 +936,7 @@ macro_rules! tuple_impls {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -961,7 +970,7 @@ macro_rules! tuple_impls {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1330,14 +1339,14 @@ impl<'de> Visitor<'de> for PathBufVisitor {
|
|||||||
formatter.write_str("path string")
|
formatter.write_str("path string")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<PathBuf, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(From::from(v))
|
Ok(From::from(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<PathBuf, E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1347,7 +1356,7 @@ impl<'de> Visitor<'de> for PathBufVisitor {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<'de> Deserialize<'de> for PathBuf {
|
impl<'de> Deserialize<'de> for PathBuf {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<PathBuf, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1380,7 +1389,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1395,7 +1404,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1413,7 +1422,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
|
|
||||||
#[cfg(all(feature = "std", any(unix, windows)))]
|
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||||
impl<'de> Deserialize<'de> for OsString {
|
impl<'de> Deserialize<'de> for OsString {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<OsString, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1463,7 +1472,7 @@ where
|
|||||||
T::Owned: Deserialize<'de>,
|
T::Owned: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1473,6 +1482,44 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
|
||||||
|
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
|
||||||
|
///
|
||||||
|
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||||
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
|
impl<'de, T: ?Sized> Deserialize<'de> for RcWeak<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
try!(Option::<T>::deserialize(deserializer));
|
||||||
|
Ok(RcWeak::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
|
||||||
|
/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
|
||||||
|
///
|
||||||
|
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||||
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
|
impl<'de, T: ?Sized> Deserialize<'de> for ArcWeak<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
try!(Option::<T>::deserialize(deserializer));
|
||||||
|
Ok(ArcWeak::new())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
|
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
macro_rules! box_forwarded_impl {
|
macro_rules! box_forwarded_impl {
|
||||||
(
|
(
|
||||||
@@ -1524,7 +1571,7 @@ impl<'de, T> Deserialize<'de> for Cell<T>
|
|||||||
where
|
where
|
||||||
T: Deserialize<'de> + Copy,
|
T: Deserialize<'de> + Copy,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1566,7 +1613,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Field {
|
impl<'de> Deserialize<'de> for Field {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1579,7 +1626,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
formatter.write_str("`secs` or `nanos`")
|
formatter.write_str("`secs` or `nanos`")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1590,7 +1637,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1618,7 +1665,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
formatter.write_str("struct Duration")
|
formatter.write_str("struct Duration")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1637,7 +1684,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1691,7 +1738,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Field {
|
impl<'de> Deserialize<'de> for Field {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1704,7 +1751,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
|
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1715,7 +1762,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1743,7 +1790,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
formatter.write_str("struct SystemTime")
|
formatter.write_str("struct SystemTime")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1762,7 +1809,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1835,7 +1882,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Field {
|
impl<'de> Deserialize<'de> for Field {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -1848,7 +1895,7 @@ where
|
|||||||
formatter.write_str("`start` or `end`")
|
formatter.write_str("`start` or `end`")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1859,7 +1906,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -1892,7 +1939,7 @@ where
|
|||||||
formatter.write_str("struct Range")
|
formatter.write_str("struct Range")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<A>(self, mut seq: A) -> Result<ops::Range<Idx>, A::Error>
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1911,7 +1958,7 @@ where
|
|||||||
Ok(start..end)
|
Ok(start..end)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<A>(self, mut map: A) -> Result<ops::Range<Idx>, A::Error>
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -1958,30 +2005,12 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
|
||||||
#[allow(deprecated)]
|
|
||||||
impl<'de, T> Deserialize<'de> for NonZero<T>
|
|
||||||
where
|
|
||||||
T: Deserialize<'de> + Zeroable,
|
|
||||||
{
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let value = try!(Deserialize::deserialize(deserializer));
|
|
||||||
match NonZero::new(value) {
|
|
||||||
Some(nonzero) => Ok(nonzero),
|
|
||||||
None => Err(Error::custom("expected a non-zero value")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! nonzero_integers {
|
macro_rules! nonzero_integers {
|
||||||
( $( $T: ty, )+ ) => {
|
( $( $T: ty, )+ ) => {
|
||||||
$(
|
$(
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
impl<'de> Deserialize<'de> for $T {
|
impl<'de> Deserialize<'de> for $T {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -2013,7 +2042,7 @@ where
|
|||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
E: Deserialize<'de>,
|
E: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -2028,7 +2057,7 @@ where
|
|||||||
|
|
||||||
impl<'de> Deserialize<'de> for Field {
|
impl<'de> Deserialize<'de> for Field {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -2041,7 +2070,7 @@ where
|
|||||||
formatter.write_str("`Ok` or `Err`")
|
formatter.write_str("`Ok` or `Err`")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_u32<E>(self, value: u32) -> Result<Field, E>
|
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -2055,7 +2084,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, value: &str) -> Result<Field, E>
|
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -2066,7 +2095,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
|
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
@@ -2100,7 +2129,7 @@ where
|
|||||||
formatter.write_str("enum Result")
|
formatter.write_str("enum Result")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_enum<A>(self, data: A) -> Result<Result<T, E>, A::Error>
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
@@ -2124,7 +2153,7 @@ impl<'de, T> Deserialize<'de> for Wrapping<T>
|
|||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
|
|||||||
+81
-36
@@ -84,7 +84,6 @@
|
|||||||
//! - LinkedList\<T\>
|
//! - LinkedList\<T\>
|
||||||
//! - VecDeque\<T\>
|
//! - VecDeque\<T\>
|
||||||
//! - Vec\<T\>
|
//! - Vec\<T\>
|
||||||
//! - EnumSet\<T\> (unstable)
|
|
||||||
//! - **Zero-copy types**:
|
//! - **Zero-copy types**:
|
||||||
//! - &str
|
//! - &str
|
||||||
//! - &[u8]
|
//! - &[u8]
|
||||||
@@ -98,7 +97,6 @@
|
|||||||
//! - Path
|
//! - Path
|
||||||
//! - PathBuf
|
//! - PathBuf
|
||||||
//! - Range\<T\>
|
//! - Range\<T\>
|
||||||
//! - NonZero\<T\> (unstable, deprecated)
|
|
||||||
//! - num::NonZero* (unstable)
|
//! - num::NonZero* (unstable)
|
||||||
//! - **Net types**:
|
//! - **Net types**:
|
||||||
//! - IpAddr
|
//! - IpAddr
|
||||||
@@ -172,7 +170,8 @@ macro_rules! declare_error_trait {
|
|||||||
///
|
///
|
||||||
/// impl<'de> Deserialize<'de> for IpAddr {
|
/// impl<'de> Deserialize<'de> for IpAddr {
|
||||||
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
/// where D: Deserializer<'de>
|
/// where
|
||||||
|
/// D: Deserializer<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// let s = try!(String::deserialize(deserializer));
|
/// let s = try!(String::deserialize(deserializer));
|
||||||
/// s.parse().map_err(de::Error::custom)
|
/// s.parse().map_err(de::Error::custom)
|
||||||
@@ -196,6 +195,7 @@ macro_rules! declare_error_trait {
|
|||||||
/// For example if we try to deserialize a String out of a JSON file
|
/// For example if we try to deserialize a String out of a JSON file
|
||||||
/// containing an integer, the unexpected type is the integer and the
|
/// containing an integer, the unexpected type is the integer and the
|
||||||
/// expected type is the string.
|
/// expected type is the string.
|
||||||
|
#[cold]
|
||||||
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
|
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
|
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
|
||||||
}
|
}
|
||||||
@@ -213,6 +213,7 @@ macro_rules! declare_error_trait {
|
|||||||
/// For example if we try to deserialize a String out of some binary data
|
/// For example if we try to deserialize a String out of some binary data
|
||||||
/// that is not valid UTF-8, the unexpected value is the bytes and the
|
/// that is not valid UTF-8, the unexpected value is the bytes and the
|
||||||
/// expected value is a string.
|
/// expected value is a string.
|
||||||
|
#[cold]
|
||||||
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
|
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
|
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
|
||||||
}
|
}
|
||||||
@@ -226,12 +227,14 @@ macro_rules! declare_error_trait {
|
|||||||
/// The `exp` argument provides information about what data was being
|
/// The `exp` argument provides information about what data was being
|
||||||
/// expected. For example `exp` might say that a tuple of size 6 was
|
/// expected. For example `exp` might say that a tuple of size 6 was
|
||||||
/// expected.
|
/// expected.
|
||||||
|
#[cold]
|
||||||
fn invalid_length(len: usize, exp: &Expected) -> Self {
|
fn invalid_length(len: usize, exp: &Expected) -> Self {
|
||||||
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
|
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raised when a `Deserialize` enum type received a variant with an
|
/// Raised when a `Deserialize` enum type received a variant with an
|
||||||
/// unrecognized name.
|
/// unrecognized name.
|
||||||
|
#[cold]
|
||||||
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
Error::custom(format_args!("unknown variant `{}`, there are no variants",
|
Error::custom(format_args!("unknown variant `{}`, there are no variants",
|
||||||
@@ -245,6 +248,7 @@ macro_rules! declare_error_trait {
|
|||||||
|
|
||||||
/// Raised when a `Deserialize` struct type received a field with an
|
/// Raised when a `Deserialize` struct type received a field with an
|
||||||
/// unrecognized name.
|
/// unrecognized name.
|
||||||
|
#[cold]
|
||||||
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
|
||||||
if expected.is_empty() {
|
if expected.is_empty() {
|
||||||
Error::custom(format_args!("unknown field `{}`, there are no fields",
|
Error::custom(format_args!("unknown field `{}`, there are no fields",
|
||||||
@@ -259,12 +263,14 @@ macro_rules! declare_error_trait {
|
|||||||
/// Raised when a `Deserialize` struct type expected to receive a required
|
/// Raised when a `Deserialize` struct type expected to receive a required
|
||||||
/// field with a particular name but that field was not present in the
|
/// field with a particular name but that field was not present in the
|
||||||
/// input.
|
/// input.
|
||||||
|
#[cold]
|
||||||
fn missing_field(field: &'static str) -> Self {
|
fn missing_field(field: &'static str) -> Self {
|
||||||
Error::custom(format_args!("missing field `{}`", field))
|
Error::custom(format_args!("missing field `{}`", field))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raised when a `Deserialize` struct type received more than one of the
|
/// Raised when a `Deserialize` struct type received more than one of the
|
||||||
/// same field.
|
/// same field.
|
||||||
|
#[cold]
|
||||||
fn duplicate_field(field: &'static str) -> Self {
|
fn duplicate_field(field: &'static str) -> Self {
|
||||||
Error::custom(format_args!("duplicate field `{}`", field))
|
Error::custom(format_args!("duplicate field `{}`", field))
|
||||||
}
|
}
|
||||||
@@ -299,7 +305,8 @@ declare_error_trait!(Error: Sized + Debug + Display);
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||||
/// where E: de::Error
|
/// where
|
||||||
|
/// E: de::Error,
|
||||||
/// {
|
/// {
|
||||||
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
|
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
|
||||||
/// }
|
/// }
|
||||||
@@ -423,7 +430,8 @@ impl<'a> fmt::Display for Unexpected<'a> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
|
||||||
/// where E: de::Error
|
/// where
|
||||||
|
/// E: de::Error,
|
||||||
/// {
|
/// {
|
||||||
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
|
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
|
||||||
/// }
|
/// }
|
||||||
@@ -436,7 +444,8 @@ impl<'a> fmt::Display for Unexpected<'a> {
|
|||||||
/// # use serde::de::{self, Unexpected};
|
/// # use serde::de::{self, Unexpected};
|
||||||
/// #
|
/// #
|
||||||
/// # fn example<E>() -> Result<(), E>
|
/// # fn example<E>() -> Result<(), E>
|
||||||
/// # where E: de::Error
|
/// # where
|
||||||
|
/// # E: de::Error,
|
||||||
/// # {
|
/// # {
|
||||||
/// # let v = true;
|
/// # let v = true;
|
||||||
/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
|
/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
|
||||||
@@ -550,11 +559,13 @@ pub trait Deserialize<'de>: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// # trait Ignore {
|
/// # trait Ignore {
|
||||||
/// fn from_str<'a, T>(s: &'a str) -> Result<T>
|
/// fn from_str<'a, T>(s: &'a str) -> Result<T>
|
||||||
/// where T: Deserialize<'a>;
|
/// where
|
||||||
|
/// T: Deserialize<'a>;
|
||||||
///
|
///
|
||||||
/// fn from_reader<R, T>(rdr: R) -> Result<T>
|
/// fn from_reader<R, T>(rdr: R) -> Result<T>
|
||||||
/// where R: Read,
|
/// where
|
||||||
/// T: DeserializeOwned;
|
/// R: Read,
|
||||||
|
/// T: DeserializeOwned;
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
|
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
|
||||||
@@ -630,7 +641,8 @@ where
|
|||||||
/// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>);
|
/// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>);
|
||||||
///
|
///
|
||||||
/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T>
|
/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T>
|
||||||
/// where T: Deserialize<'de>
|
/// where
|
||||||
|
/// T: Deserialize<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // The return type of the `deserialize` method. This implementation
|
/// // The return type of the `deserialize` method. This implementation
|
||||||
/// // appends onto an existing vector but does not create any new data
|
/// // appends onto an existing vector but does not create any new data
|
||||||
@@ -638,14 +650,16 @@ where
|
|||||||
/// type Value = ();
|
/// type Value = ();
|
||||||
///
|
///
|
||||||
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
/// where D: Deserializer<'de>
|
/// where
|
||||||
|
/// D: Deserializer<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // Visitor implementation that will walk an inner array of the JSON
|
/// // Visitor implementation that will walk an inner array of the JSON
|
||||||
/// // input.
|
/// // input.
|
||||||
/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>);
|
/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>);
|
||||||
///
|
///
|
||||||
/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T>
|
/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T>
|
||||||
/// where T: Deserialize<'de>
|
/// where
|
||||||
|
/// T: Deserialize<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// type Value = ();
|
/// type Value = ();
|
||||||
///
|
///
|
||||||
@@ -654,7 +668,8 @@ where
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
/// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
|
||||||
/// where A: SeqAccess<'de>
|
/// where
|
||||||
|
/// A: SeqAccess<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // Visit each element in the inner array and push it onto
|
/// // Visit each element in the inner array and push it onto
|
||||||
/// // the existing vector.
|
/// // the existing vector.
|
||||||
@@ -673,7 +688,8 @@ where
|
|||||||
/// struct FlattenedVecVisitor<T>(PhantomData<T>);
|
/// struct FlattenedVecVisitor<T>(PhantomData<T>);
|
||||||
///
|
///
|
||||||
/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T>
|
/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T>
|
||||||
/// where T: Deserialize<'de>
|
/// where
|
||||||
|
/// T: Deserialize<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // This Visitor constructs a single Vec<T> to hold the flattened
|
/// // This Visitor constructs a single Vec<T> to hold the flattened
|
||||||
/// // contents of the inner arrays.
|
/// // contents of the inner arrays.
|
||||||
@@ -684,7 +700,8 @@ where
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
|
/// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
|
||||||
/// where A: SeqAccess<'de>
|
/// where
|
||||||
|
/// A: SeqAccess<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // Create a single Vec to hold the flattened contents.
|
/// // Create a single Vec to hold the flattened contents.
|
||||||
/// let mut vec = Vec::new();
|
/// let mut vec = Vec::new();
|
||||||
@@ -700,7 +717,8 @@ where
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
|
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
|
||||||
/// # where D: Deserializer<'de>
|
/// # where
|
||||||
|
/// # D: Deserializer<'de>,
|
||||||
/// # {
|
/// # {
|
||||||
/// let visitor = FlattenedVecVisitor(PhantomData);
|
/// let visitor = FlattenedVecVisitor(PhantomData);
|
||||||
/// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?;
|
/// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?;
|
||||||
@@ -1085,7 +1103,8 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
///
|
///
|
||||||
/// impl<'de> Deserialize<'de> for Timestamp {
|
/// impl<'de> Deserialize<'de> for Timestamp {
|
||||||
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
/// where D: Deserializer<'de>
|
/// where
|
||||||
|
/// D: Deserializer<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// if deserializer.is_human_readable() {
|
/// if deserializer.is_human_readable() {
|
||||||
/// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
|
/// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
|
||||||
@@ -1136,7 +1155,8 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||||
/// where E: de::Error
|
/// where
|
||||||
|
/// E: de::Error,
|
||||||
/// {
|
/// {
|
||||||
/// if s.len() >= self.min {
|
/// if s.len() >= self.min {
|
||||||
/// Ok(s.to_owned())
|
/// Ok(s.to_owned())
|
||||||
@@ -1507,6 +1527,15 @@ pub trait Visitor<'de>: Sized {
|
|||||||
let _ = data;
|
let _ = data;
|
||||||
Err(Error::invalid_type(Unexpected::Enum, &self))
|
Err(Error::invalid_type(Unexpected::Enum, &self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when deserializing a flattened Option field. Not public API.
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Err(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1816,15 +1845,18 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// }
|
/// }
|
||||||
/// #
|
/// #
|
||||||
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
||||||
/// # where T: DeserializeSeed<'de>
|
/// # where
|
||||||
|
/// # T: DeserializeSeed<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -1851,7 +1883,8 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
|
/// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
|
||||||
/// where T: DeserializeSeed<'de>
|
/// where
|
||||||
|
/// T: DeserializeSeed<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // What the data actually contained; suppose it is a unit variant.
|
/// // What the data actually contained; suppose it is a unit variant.
|
||||||
/// let unexp = Unexpected::UnitVariant;
|
/// let unexp = Unexpected::UnitVariant;
|
||||||
@@ -1859,11 +1892,13 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// }
|
/// }
|
||||||
/// #
|
/// #
|
||||||
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -1904,13 +1939,17 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
||||||
/// # where T: DeserializeSeed<'de>
|
/// # where
|
||||||
|
/// # T: DeserializeSeed<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// fn tuple_variant<V>(self,
|
/// fn tuple_variant<V>(
|
||||||
/// _len: usize,
|
/// self,
|
||||||
/// _visitor: V) -> Result<V::Value, Self::Error>
|
/// _len: usize,
|
||||||
/// where V: Visitor<'de>
|
/// _visitor: V,
|
||||||
|
/// ) -> Result<V::Value, Self::Error>
|
||||||
|
/// where
|
||||||
|
/// V: Visitor<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // What the data actually contained; suppose it is a unit variant.
|
/// // What the data actually contained; suppose it is a unit variant.
|
||||||
/// let unexp = Unexpected::UnitVariant;
|
/// let unexp = Unexpected::UnitVariant;
|
||||||
@@ -1918,7 +1957,8 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// }
|
/// }
|
||||||
/// #
|
/// #
|
||||||
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -1946,17 +1986,22 @@ pub trait VariantAccess<'de>: Sized {
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
|
||||||
/// # where T: DeserializeSeed<'de>
|
/// # where
|
||||||
|
/// # T: DeserializeSeed<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # { unimplemented!() }
|
/// # { unimplemented!() }
|
||||||
/// #
|
/// #
|
||||||
/// fn struct_variant<V>(self,
|
/// fn struct_variant<V>(
|
||||||
/// _fields: &'static [&'static str],
|
/// self,
|
||||||
/// _visitor: V) -> Result<V::Value, Self::Error>
|
/// _fields: &'static [&'static str],
|
||||||
/// where V: Visitor<'de>
|
/// _visitor: V,
|
||||||
|
/// ) -> Result<V::Value, Self::Error>
|
||||||
|
/// where
|
||||||
|
/// V: Visitor<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// // What the data actually contained; suppose it is a unit variant.
|
/// // What the data actually contained; suppose it is a unit variant.
|
||||||
/// let unexp = Unexpected::UnitVariant;
|
/// let unexp = Unexpected::UnitVariant;
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ type ErrorImpl = ();
|
|||||||
|
|
||||||
impl de::Error for Error {
|
impl de::Error for Error {
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -68,6 +69,7 @@ impl de::Error for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -78,6 +80,7 @@ impl de::Error for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ser::Error for Error {
|
impl ser::Error for Error {
|
||||||
|
#[cold]
|
||||||
fn custom<T>(msg: T) -> Self
|
fn custom<T>(msg: T) -> Self
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ pub use lib::result::Result::{self, Err, Ok};
|
|||||||
|
|
||||||
pub use self::string::from_utf8_lossy;
|
pub use self::string::from_utf8_lossy;
|
||||||
|
|
||||||
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
|
pub use lib::Vec;
|
||||||
|
|
||||||
mod string {
|
mod string {
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
|
|||||||
+6
-10
@@ -79,14 +79,14 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Serde types in rustdoc of other crates get linked to here.
|
// Serde types in rustdoc of other crates get linked to here.
|
||||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.40")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.57")]
|
||||||
// Support using Serde without the standard library!
|
// Support using Serde without the standard library!
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
// Unstable functionality only if the user asks for it. For tracking and
|
// Unstable functionality only if the user asks for it. For tracking and
|
||||||
// discussion of these features please refer to this issue:
|
// discussion of these features please refer to this issue:
|
||||||
//
|
//
|
||||||
// https://github.com/serde-rs/serde/issues/812
|
// https://github.com/serde-rs/serde/issues/812
|
||||||
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
|
#![cfg_attr(feature = "unstable", feature(specialization))]
|
||||||
#![cfg_attr(feature = "alloc", feature(alloc))]
|
#![cfg_attr(feature = "alloc", feature(alloc))]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
@@ -179,14 +179,14 @@ mod lib {
|
|||||||
pub use std::boxed::Box;
|
pub use std::boxed::Box;
|
||||||
|
|
||||||
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
||||||
pub use alloc::rc::Rc;
|
pub use alloc::rc::{Rc, Weak as RcWeak};
|
||||||
#[cfg(all(feature = "rc", feature = "std"))]
|
#[cfg(all(feature = "rc", feature = "std"))]
|
||||||
pub use std::rc::Rc;
|
pub use std::rc::{Rc, Weak as RcWeak};
|
||||||
|
|
||||||
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
|
||||||
pub use alloc::arc::Arc;
|
pub use alloc::arc::{Arc, Weak as ArcWeak};
|
||||||
#[cfg(all(feature = "rc", feature = "std"))]
|
#[cfg(all(feature = "rc", feature = "std"))]
|
||||||
pub use std::sync::Arc;
|
pub use std::sync::{Arc, Weak as ArcWeak};
|
||||||
|
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
||||||
@@ -213,10 +213,6 @@ mod lib {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
|
||||||
#[allow(deprecated)]
|
|
||||||
pub use core::nonzero::{NonZero, Zeroable};
|
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
pub use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
|
pub use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -31,14 +31,16 @@
|
|||||||
/// # type Error = value::Error;
|
/// # type Error = value::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
|
/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
|
||||||
/// # where V: Visitor<'de>
|
/// # where
|
||||||
|
/// # V: Visitor<'de>,
|
||||||
/// # {
|
/// # {
|
||||||
/// # unimplemented!()
|
/// # unimplemented!()
|
||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// #[inline]
|
/// #[inline]
|
||||||
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
/// where V: Visitor<'de>
|
/// where
|
||||||
|
/// V: Visitor<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// self.deserialize_any(visitor)
|
/// self.deserialize_any(visitor)
|
||||||
/// }
|
/// }
|
||||||
@@ -69,7 +71,8 @@
|
|||||||
/// # type Error = value::Error;
|
/// # type Error = value::Error;
|
||||||
/// #
|
/// #
|
||||||
/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
/// where V: Visitor<'de>
|
/// where
|
||||||
|
/// V: Visitor<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// /* ... */
|
/// /* ... */
|
||||||
/// # let _ = visitor;
|
/// # let _ = visitor;
|
||||||
@@ -105,7 +108,8 @@
|
|||||||
/// # type Error = value::Error;
|
/// # type Error = value::Error;
|
||||||
/// #
|
/// #
|
||||||
/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
|
/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
|
||||||
/// # where W: Visitor<'q>
|
/// # where
|
||||||
|
/// # W: Visitor<'q>,
|
||||||
/// # {
|
/// # {
|
||||||
/// # unimplemented!()
|
/// # unimplemented!()
|
||||||
/// # }
|
/// # }
|
||||||
|
|||||||
+183
-106
@@ -14,10 +14,11 @@ use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Vi
|
|||||||
use de::{MapAccess, Unexpected};
|
use de::{MapAccess, Unexpected};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub use self::content::{Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
|
pub use self::content::{
|
||||||
InternallyTaggedUnitVisitor, TagContentOtherField,
|
Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
|
||||||
TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor,
|
InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
|
||||||
TaggedContentVisitor, UntaggedUnitVisitor};
|
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
|
||||||
|
};
|
||||||
|
|
||||||
/// If the missing field is of type `Option<T>` then treat is as `None`,
|
/// If the missing field is of type `Option<T>` then treat is as `None`,
|
||||||
/// otherwise it is an error.
|
/// otherwise it is an error.
|
||||||
@@ -229,8 +230,10 @@ mod content {
|
|||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use super::size_hint;
|
use super::size_hint;
|
||||||
use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
|
use de::{
|
||||||
SeqAccess, Unexpected, Visitor};
|
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
|
||||||
|
SeqAccess, Unexpected, Visitor,
|
||||||
|
};
|
||||||
|
|
||||||
/// Used from generated code to buffer the contents of the Deserializer when
|
/// Used from generated code to buffer the contents of the Deserializer when
|
||||||
/// deserializing untagged enums and internally tagged enums.
|
/// deserializing untagged enums and internally tagged enums.
|
||||||
@@ -273,10 +276,13 @@ mod content {
|
|||||||
match *self {
|
match *self {
|
||||||
Content::Str(x) => Some(x),
|
Content::Str(x) => Some(x),
|
||||||
Content::String(ref x) => Some(x),
|
Content::String(ref x) => Some(x),
|
||||||
|
Content::Bytes(x) => str::from_utf8(x).ok(),
|
||||||
|
Content::ByteBuf(ref x) => str::from_utf8(x).ok(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
fn unexpected(&self) -> Unexpected {
|
fn unexpected(&self) -> Unexpected {
|
||||||
match *self {
|
match *self {
|
||||||
Content::Bool(b) => Unexpected::Bool(b),
|
Content::Bool(b) => Unexpected::Bool(b),
|
||||||
@@ -1021,6 +1027,23 @@ mod content {
|
|||||||
fn invalid_type(self, exp: &Expected) -> E {
|
fn invalid_type(self, exp: &Expected) -> E {
|
||||||
de::Error::invalid_type(self.content.unexpected(), exp)
|
de::Error::invalid_type(self.content.unexpected(), exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
match self.content {
|
||||||
|
Content::U8(v) => visitor.visit_u8(v),
|
||||||
|
Content::U16(v) => visitor.visit_u16(v),
|
||||||
|
Content::U32(v) => visitor.visit_u32(v),
|
||||||
|
Content::U64(v) => visitor.visit_u64(v),
|
||||||
|
Content::I8(v) => visitor.visit_i8(v),
|
||||||
|
Content::I16(v) => visitor.visit_i16(v),
|
||||||
|
Content::I32(v) => visitor.visit_i32(v),
|
||||||
|
Content::I64(v) => visitor.visit_i64(v),
|
||||||
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
|
fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
|
||||||
@@ -1104,94 +1127,56 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I8(v) => visitor.visit_i8(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I16(v) => visitor.visit_i16(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I32(v) => visitor.visit_i32(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U8(v) => visitor.visit_u8(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U16(v) => visitor.visit_u16(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U32(v) => visitor.visit_u32(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
@@ -1330,7 +1315,10 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_newtype_struct(self)
|
match self.content {
|
||||||
|
Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
|
||||||
|
_ => visitor.visit_newtype_struct(self),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
@@ -1437,6 +1425,8 @@ mod content {
|
|||||||
match self.content {
|
match self.content {
|
||||||
Content::String(v) => visitor.visit_string(v),
|
Content::String(v) => visitor.visit_string(v),
|
||||||
Content::Str(v) => visitor.visit_borrowed_str(v),
|
Content::Str(v) => visitor.visit_borrowed_str(v),
|
||||||
|
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
|
||||||
|
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1746,6 +1736,23 @@ mod content {
|
|||||||
fn invalid_type(self, exp: &Expected) -> E {
|
fn invalid_type(self, exp: &Expected) -> E {
|
||||||
de::Error::invalid_type(self.content.unexpected(), exp)
|
de::Error::invalid_type(self.content.unexpected(), exp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
match *self.content {
|
||||||
|
Content::U8(v) => visitor.visit_u8(v),
|
||||||
|
Content::U16(v) => visitor.visit_u16(v),
|
||||||
|
Content::U32(v) => visitor.visit_u32(v),
|
||||||
|
Content::U64(v) => visitor.visit_u64(v),
|
||||||
|
Content::I8(v) => visitor.visit_i8(v),
|
||||||
|
Content::I16(v) => visitor.visit_i16(v),
|
||||||
|
Content::I32(v) => visitor.visit_i32(v),
|
||||||
|
Content::I64(v) => visitor.visit_i64(v),
|
||||||
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_content_seq_ref<'a, 'de, V, E>(
|
fn visit_content_seq_ref<'a, 'de, V, E>(
|
||||||
@@ -1837,94 +1844,56 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I8(v) => visitor.visit_i8(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I16(v) => visitor.visit_i16(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::I32(v) => visitor.visit_i32(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U8(v) => visitor.visit_u8(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U16(v) => visitor.visit_u16(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U32(v) => visitor.visit_u32(v),
|
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
match *self.content {
|
self.deserialize_integer(visitor)
|
||||||
Content::U64(v) => visitor.visit_u64(v),
|
|
||||||
Content::I64(v) => visitor.visit_i64(v),
|
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
@@ -2042,7 +2011,12 @@ mod content {
|
|||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
visitor.visit_newtype_struct(self)
|
match *self.content {
|
||||||
|
Content::Newtype(ref v) => {
|
||||||
|
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
|
||||||
|
}
|
||||||
|
_ => visitor.visit_newtype_struct(self),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
@@ -2153,6 +2127,8 @@ mod content {
|
|||||||
match *self.content {
|
match *self.content {
|
||||||
Content::String(ref v) => visitor.visit_str(v),
|
Content::String(ref v) => visitor.visit_str(v),
|
||||||
Content::Str(v) => visitor.visit_borrowed_str(v),
|
Content::Str(v) => visitor.visit_borrowed_str(v),
|
||||||
|
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
|
||||||
|
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2670,6 +2646,30 @@ pub struct FlatMapDeserializer<'a, 'de: 'a, E>(
|
|||||||
pub PhantomData<E>,
|
pub PhantomData<E>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
fn deserialize_other<V>() -> Result<V, E> {
|
||||||
|
Err(Error::custom("can only flatten structs and maps"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
macro_rules! forward_to_deserialize_other {
|
||||||
|
($($func:ident ( $($arg:ty),* ))*) => {
|
||||||
|
$(
|
||||||
|
fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
|
Self::deserialize_other()
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
|
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
|
||||||
where
|
where
|
||||||
@@ -2677,11 +2677,15 @@ where
|
|||||||
{
|
{
|
||||||
type Error = E;
|
type Error = E;
|
||||||
|
|
||||||
fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
Err(Error::custom("can only flatten structs and maps"))
|
visitor.visit_map(FlatInternallyTaggedAccess {
|
||||||
|
iter: self.0.iter_mut(),
|
||||||
|
pending: None,
|
||||||
|
_marker: PhantomData,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_enum<V>(
|
fn deserialize_enum<V>(
|
||||||
@@ -2740,10 +2744,40 @@ where
|
|||||||
visitor.visit_newtype_struct(self)
|
visitor.visit_newtype_struct(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
|
where
|
||||||
byte_buf option unit unit_struct seq tuple tuple_struct identifier
|
V: Visitor<'de>,
|
||||||
ignored_any
|
{
|
||||||
|
match visitor.__private_visit_untagged_option(self) {
|
||||||
|
Ok(value) => Ok(value),
|
||||||
|
Err(()) => Self::deserialize_other(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_to_deserialize_other! {
|
||||||
|
deserialize_bool()
|
||||||
|
deserialize_i8()
|
||||||
|
deserialize_i16()
|
||||||
|
deserialize_i32()
|
||||||
|
deserialize_i64()
|
||||||
|
deserialize_u8()
|
||||||
|
deserialize_u16()
|
||||||
|
deserialize_u32()
|
||||||
|
deserialize_u64()
|
||||||
|
deserialize_f32()
|
||||||
|
deserialize_f64()
|
||||||
|
deserialize_char()
|
||||||
|
deserialize_str()
|
||||||
|
deserialize_string()
|
||||||
|
deserialize_bytes()
|
||||||
|
deserialize_byte_buf()
|
||||||
|
deserialize_unit()
|
||||||
|
deserialize_unit_struct(&'static str)
|
||||||
|
deserialize_seq()
|
||||||
|
deserialize_tuple(usize)
|
||||||
|
deserialize_tuple_struct(&'static str, usize)
|
||||||
|
deserialize_identifier()
|
||||||
|
deserialize_ignored_any()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2816,3 +2850,46 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> {
|
||||||
|
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||||
|
pending: Option<&'a Content<'de>>,
|
||||||
|
_marker: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||||
|
where
|
||||||
|
T: DeserializeSeed<'de>,
|
||||||
|
{
|
||||||
|
match self.iter.next() {
|
||||||
|
Some(item) => {
|
||||||
|
// Do not take(), instead borrow this entry. The internally tagged
|
||||||
|
// enum does its own buffering so we can't tell whether this entry
|
||||||
|
// is going to be consumed. Borrowing here leaves the entry
|
||||||
|
// available for later flattened fields.
|
||||||
|
let (ref key, ref content) = *item.as_ref().unwrap();
|
||||||
|
self.pending = Some(content);
|
||||||
|
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
|
||||||
|
}
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||||
|
where
|
||||||
|
T: DeserializeSeed<'de>,
|
||||||
|
{
|
||||||
|
match self.pending.take() {
|
||||||
|
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
|
||||||
|
None => panic!("value is missing"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ use lib::*;
|
|||||||
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
|
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use self::content::{Content, ContentSerializer, SerializeStructVariantAsMapValue,
|
use self::content::{
|
||||||
SerializeTupleVariantAsMapValue};
|
Content, ContentSerializer, SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue,
|
||||||
|
};
|
||||||
|
|
||||||
/// Used to check that serde(getter) attributes return the expected type.
|
/// Used to check that serde(getter) attributes return the expected type.
|
||||||
/// Not public API.
|
/// Not public API.
|
||||||
@@ -1121,14 +1122,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||||
Err(self.bad_type(Unsupported::Optional))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
|
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
Err(self.bad_type(Unsupported::Optional))
|
value.serialize(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||||
|
|||||||
+25
-5
@@ -374,20 +374,40 @@ deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwne
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||||
#[allow(deprecated)]
|
///
|
||||||
impl<T> Serialize for NonZero<T>
|
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||||
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
|
impl<T: ?Sized> Serialize for RcWeak<T>
|
||||||
where
|
where
|
||||||
T: Serialize + Zeroable + Clone,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
self.clone().get().serialize(serializer)
|
self.upgrade().serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||||
|
///
|
||||||
|
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
||||||
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
|
impl<T: ?Sized> Serialize for ArcWeak<T>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
self.upgrade().serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
macro_rules! nonzero_integers {
|
macro_rules! nonzero_integers {
|
||||||
( $( $T: ident, )+ ) => {
|
( $( $T: ident, )+ ) => {
|
||||||
$(
|
$(
|
||||||
|
|||||||
@@ -10,8 +10,10 @@
|
|||||||
|
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
use ser::{self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
use ser::{
|
||||||
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant};
|
self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
||||||
|
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
|
||||||
|
};
|
||||||
|
|
||||||
/// Helper type for implementing a `Serializer` that does not support
|
/// Helper type for implementing a `Serializer` that does not support
|
||||||
/// serializing one of the compound types.
|
/// serializing one of the compound types.
|
||||||
|
|||||||
+110
-60
@@ -81,7 +81,6 @@
|
|||||||
//! - LinkedList\<T\>
|
//! - LinkedList\<T\>
|
||||||
//! - VecDeque\<T\>
|
//! - VecDeque\<T\>
|
||||||
//! - Vec\<T\>
|
//! - Vec\<T\>
|
||||||
//! - EnumSet\<T\> (unstable)
|
|
||||||
//! - **FFI types**:
|
//! - **FFI types**:
|
||||||
//! - CStr
|
//! - CStr
|
||||||
//! - CString
|
//! - CString
|
||||||
@@ -93,7 +92,6 @@
|
|||||||
//! - Path
|
//! - Path
|
||||||
//! - PathBuf
|
//! - PathBuf
|
||||||
//! - Range\<T\>
|
//! - Range\<T\>
|
||||||
//! - NonZero\<T\> (unstable, deprecated)
|
|
||||||
//! - num::NonZero* (unstable)
|
//! - num::NonZero* (unstable)
|
||||||
//! - **Net types**:
|
//! - **Net types**:
|
||||||
//! - IpAddr
|
//! - IpAddr
|
||||||
@@ -152,7 +150,8 @@ macro_rules! declare_error_trait {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Path {
|
/// impl Serialize for Path {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, 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) => serializer.serialize_str(s),
|
/// Some(s) => serializer.serialize_str(s),
|
||||||
@@ -223,7 +222,8 @@ pub trait Serialize {
|
|||||||
/// // This is what #[derive(Serialize)] would generate.
|
/// // This is what #[derive(Serialize)] would generate.
|
||||||
/// impl Serialize for Person {
|
/// impl Serialize for Person {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut s = serializer.serialize_struct("Person", 3)?;
|
/// let mut s = serializer.serialize_struct("Person", 3)?;
|
||||||
/// s.serialize_field("name", &self.name)?;
|
/// s.serialize_field("name", &self.name)?;
|
||||||
@@ -377,7 +377,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for bool {
|
/// impl Serialize for bool {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_bool(*self)
|
/// serializer.serialize_bool(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -403,7 +404,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for i8 {
|
/// impl Serialize for i8 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_i8(*self)
|
/// serializer.serialize_i8(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -429,7 +431,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for i16 {
|
/// impl Serialize for i16 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_i16(*self)
|
/// serializer.serialize_i16(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -455,7 +458,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for i32 {
|
/// impl Serialize for i32 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_i32(*self)
|
/// serializer.serialize_i32(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -477,7 +481,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for i64 {
|
/// impl Serialize for i64 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_i64(*self)
|
/// serializer.serialize_i64(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -503,7 +508,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for u8 {
|
/// impl Serialize for u8 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_u8(*self)
|
/// serializer.serialize_u8(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -529,7 +535,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for u16 {
|
/// impl Serialize for u16 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_u16(*self)
|
/// serializer.serialize_u16(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -555,7 +562,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for u32 {
|
/// impl Serialize for u32 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_u32(*self)
|
/// serializer.serialize_u32(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -577,7 +585,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for u64 {
|
/// impl Serialize for u64 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_u64(*self)
|
/// serializer.serialize_u64(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -603,7 +612,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for f32 {
|
/// impl Serialize for f32 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_f32(*self)
|
/// serializer.serialize_f32(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -625,7 +635,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for f64 {
|
/// impl Serialize for f64 {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_f64(*self)
|
/// serializer.serialize_f64(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -650,7 +661,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for char {
|
/// impl Serialize for char {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_char(*self)
|
/// serializer.serialize_char(*self)
|
||||||
/// }
|
/// }
|
||||||
@@ -672,7 +684,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for str {
|
/// impl Serialize for str {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, 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)
|
||||||
/// }
|
/// }
|
||||||
@@ -737,10 +750,12 @@ pub trait Serializer: Sized {
|
|||||||
/// # use Option::{Some, None};
|
/// # use Option::{Some, None};
|
||||||
/// #
|
/// #
|
||||||
/// impl<T> Serialize for Option<T>
|
/// impl<T> Serialize for Option<T>
|
||||||
/// where T: Serialize
|
/// where
|
||||||
|
/// T: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// Some(ref value) => serializer.serialize_some(value),
|
/// Some(ref value) => serializer.serialize_some(value),
|
||||||
@@ -770,10 +785,12 @@ pub trait Serializer: Sized {
|
|||||||
/// # use Option::{Some, None};
|
/// # use Option::{Some, None};
|
||||||
/// #
|
/// #
|
||||||
/// impl<T> Serialize for Option<T>
|
/// impl<T> Serialize for Option<T>
|
||||||
/// where T: Serialize
|
/// where
|
||||||
|
/// T: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// Some(ref value) => serializer.serialize_some(value),
|
/// Some(ref value) => serializer.serialize_some(value),
|
||||||
@@ -802,7 +819,8 @@ pub trait Serializer: Sized {
|
|||||||
/// #
|
/// #
|
||||||
/// impl Serialize for () {
|
/// impl Serialize for () {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, 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()
|
||||||
/// }
|
/// }
|
||||||
@@ -823,7 +841,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Nothing {
|
/// impl Serialize for Nothing {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_unit_struct("Nothing")
|
/// serializer.serialize_unit_struct("Nothing")
|
||||||
/// }
|
/// }
|
||||||
@@ -847,7 +866,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
|
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
|
||||||
@@ -876,7 +896,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Millimeters {
|
/// impl Serialize for Millimeters {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
|
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
|
||||||
/// }
|
/// }
|
||||||
@@ -906,7 +927,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s),
|
/// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s),
|
||||||
@@ -956,10 +978,12 @@ pub trait Serializer: Sized {
|
|||||||
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
|
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
|
||||||
///
|
///
|
||||||
/// impl<T> Serialize for Vec<T>
|
/// impl<T> Serialize for Vec<T>
|
||||||
/// where T: Serialize
|
/// where
|
||||||
|
/// T: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
||||||
/// for element in self {
|
/// for element in self {
|
||||||
@@ -988,12 +1012,14 @@ pub trait Serializer: Sized {
|
|||||||
/// # struct Tuple3<A, B, C>(A, B, C);
|
/// # struct Tuple3<A, B, C>(A, B, C);
|
||||||
/// #
|
/// #
|
||||||
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
|
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
|
||||||
/// where A: Serialize,
|
/// where
|
||||||
/// B: Serialize,
|
/// A: Serialize,
|
||||||
/// C: Serialize
|
/// B: Serialize,
|
||||||
|
/// C: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut tup = serializer.serialize_tuple(3)?;
|
/// let mut tup = serializer.serialize_tuple(3)?;
|
||||||
/// tup.serialize_element(&self.0)?;
|
/// tup.serialize_element(&self.0)?;
|
||||||
@@ -1012,7 +1038,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Vram {
|
/// impl Serialize for Vram {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?;
|
/// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?;
|
||||||
/// for element in &self.0[..] {
|
/// for element in &self.0[..] {
|
||||||
@@ -1038,7 +1065,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Rgb {
|
/// impl Serialize for Rgb {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
|
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
|
||||||
/// ts.serialize_field(&self.0)?;
|
/// ts.serialize_field(&self.0)?;
|
||||||
@@ -1072,7 +1100,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::T(ref a, ref b) => {
|
/// E::T(ref a, ref b) => {
|
||||||
@@ -1130,11 +1159,13 @@ pub trait Serializer: Sized {
|
|||||||
/// use serde::ser::{Serialize, Serializer, SerializeMap};
|
/// use serde::ser::{Serialize, Serializer, SerializeMap};
|
||||||
///
|
///
|
||||||
/// impl<K, V> Serialize for HashMap<K, V>
|
/// impl<K, V> Serialize for HashMap<K, V>
|
||||||
/// where K: Serialize,
|
/// where
|
||||||
/// V: Serialize
|
/// K: Serialize,
|
||||||
|
/// V: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut map = serializer.serialize_map(Some(self.len()))?;
|
/// let mut map = serializer.serialize_map(Some(self.len()))?;
|
||||||
/// for (k, v) in self {
|
/// for (k, v) in self {
|
||||||
@@ -1164,7 +1195,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Rgb {
|
/// impl Serialize for Rgb {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
|
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
|
||||||
/// rgb.serialize_field("r", &self.r)?;
|
/// rgb.serialize_field("r", &self.r)?;
|
||||||
@@ -1197,7 +1229,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::S { ref r, ref g, ref b } => {
|
/// E::S { ref r, ref g, ref b } => {
|
||||||
@@ -1234,7 +1267,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for SecretlyOneHigher {
|
/// impl Serialize for SecretlyOneHigher {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.collect_seq(self.data.iter().map(|x| x + 1))
|
/// serializer.collect_seq(self.data.iter().map(|x| x + 1))
|
||||||
/// }
|
/// }
|
||||||
@@ -1272,7 +1306,8 @@ pub trait Serializer: Sized {
|
|||||||
/// // Serializes as a map in which the values are all unit.
|
/// // Serializes as a map in which the values are all unit.
|
||||||
/// impl Serialize for MapToUnit {
|
/// impl Serialize for MapToUnit {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.collect_map(self.keys.iter().map(|k| (k, ())))
|
/// serializer.collect_map(self.keys.iter().map(|k| (k, ())))
|
||||||
/// }
|
/// }
|
||||||
@@ -1312,7 +1347,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for DateTime {
|
/// impl Serialize for DateTime {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.collect_str(&format_args!("{:?}{:?}",
|
/// serializer.collect_str(&format_args!("{:?}{:?}",
|
||||||
/// self.naive_local(),
|
/// self.naive_local(),
|
||||||
@@ -1352,7 +1388,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for DateTime {
|
/// impl Serialize for DateTime {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// serializer.collect_str(&format_args!("{:?}{:?}",
|
/// serializer.collect_str(&format_args!("{:?}{:?}",
|
||||||
/// self.naive_local(),
|
/// self.naive_local(),
|
||||||
@@ -1393,7 +1430,8 @@ pub trait Serializer: Sized {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Timestamp {
|
/// impl Serialize for Timestamp {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// if serializer.is_human_readable() {
|
/// if serializer.is_human_readable() {
|
||||||
/// // Serialize to a human-readable string "2015-05-15T17:01:00Z".
|
/// // Serialize to a human-readable string "2015-05-15T17:01:00Z".
|
||||||
@@ -1442,10 +1480,12 @@ pub trait Serializer: Sized {
|
|||||||
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
|
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
|
||||||
///
|
///
|
||||||
/// impl<T> Serialize for Vec<T>
|
/// impl<T> Serialize for Vec<T>
|
||||||
/// where T: Serialize
|
/// where
|
||||||
|
/// T: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
|
||||||
/// for element in self {
|
/// for element in self {
|
||||||
@@ -1485,12 +1525,14 @@ pub trait SerializeSeq {
|
|||||||
/// # struct Tuple3<A, B, C>(A, B, C);
|
/// # struct Tuple3<A, B, C>(A, B, C);
|
||||||
/// #
|
/// #
|
||||||
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
|
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
|
||||||
/// where A: Serialize,
|
/// where
|
||||||
/// B: Serialize,
|
/// A: Serialize,
|
||||||
/// C: Serialize
|
/// B: Serialize,
|
||||||
|
/// C: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut tup = serializer.serialize_tuple(3)?;
|
/// let mut tup = serializer.serialize_tuple(3)?;
|
||||||
/// tup.serialize_element(&self.0)?;
|
/// tup.serialize_element(&self.0)?;
|
||||||
@@ -1529,10 +1571,12 @@ pub trait SerializeSeq {
|
|||||||
/// # }
|
/// # }
|
||||||
/// #
|
/// #
|
||||||
/// # impl<T> Serialize for Array<T>
|
/// # impl<T> Serialize for Array<T>
|
||||||
/// where T: Serialize
|
/// where
|
||||||
|
/// T: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut seq = serializer.serialize_tuple(16)?;
|
/// let mut seq = serializer.serialize_tuple(16)?;
|
||||||
/// for element in self {
|
/// for element in self {
|
||||||
@@ -1567,7 +1611,8 @@ pub trait SerializeTuple {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Rgb {
|
/// impl Serialize for Rgb {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
|
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
|
||||||
/// ts.serialize_field(&self.0)?;
|
/// ts.serialize_field(&self.0)?;
|
||||||
@@ -1605,7 +1650,8 @@ pub trait SerializeTupleStruct {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::T(ref a, ref b) => {
|
/// E::T(ref a, ref b) => {
|
||||||
@@ -1666,11 +1712,13 @@ pub trait SerializeTupleVariant {
|
|||||||
/// use serde::ser::{Serialize, Serializer, SerializeMap};
|
/// use serde::ser::{Serialize, Serializer, SerializeMap};
|
||||||
///
|
///
|
||||||
/// impl<K, V> Serialize for HashMap<K, V>
|
/// impl<K, V> Serialize for HashMap<K, V>
|
||||||
/// where K: Serialize,
|
/// where
|
||||||
/// V: Serialize
|
/// K: Serialize,
|
||||||
|
/// V: Serialize,
|
||||||
/// {
|
/// {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut map = serializer.serialize_map(Some(self.len()))?;
|
/// let mut map = serializer.serialize_map(Some(self.len()))?;
|
||||||
/// for (k, v) in self {
|
/// for (k, v) in self {
|
||||||
@@ -1754,7 +1802,8 @@ pub trait SerializeMap {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Rgb {
|
/// impl Serialize for Rgb {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
|
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
|
||||||
/// rgb.serialize_field("r", &self.r)?;
|
/// rgb.serialize_field("r", &self.r)?;
|
||||||
@@ -1802,7 +1851,8 @@ pub trait SerializeStruct {
|
|||||||
///
|
///
|
||||||
/// impl Serialize for E {
|
/// impl Serialize for E {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// match *self {
|
/// match *self {
|
||||||
/// E::S { ref r, ref g, ref b } => {
|
/// E::S { ref r, ref g, ref b } => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.40" # remember to update html_root_url
|
version = "1.0.57" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@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)]"
|
||||||
@@ -24,8 +24,7 @@ proc-macro = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "0.3"
|
proc-macro2 = "0.3"
|
||||||
quote = "0.5"
|
quote = "0.5.2"
|
||||||
serde_derive_internals = { version = "=0.23.1", default-features = false, path = "../serde_derive_internals" }
|
|
||||||
syn = { version = "0.13", features = ["visit"] }
|
syn = { version = "0.13", features = ["visit"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -65,6 +65,28 @@ pub fn with_where_predicates_from_fields(
|
|||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_where_predicates_from_variants(
|
||||||
|
cont: &Container,
|
||||||
|
generics: &syn::Generics,
|
||||||
|
from_variant: fn(&attr::Variant) -> Option<&[syn::WherePredicate]>,
|
||||||
|
) -> syn::Generics {
|
||||||
|
let variants = match cont.data {
|
||||||
|
Data::Enum(ref variants) => variants,
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return generics.clone();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let predicates = variants
|
||||||
|
.iter()
|
||||||
|
.flat_map(|variant| from_variant(&variant.attrs))
|
||||||
|
.flat_map(|predicates| predicates.to_vec());
|
||||||
|
|
||||||
|
let mut generics = generics.clone();
|
||||||
|
generics.make_where_clause().predicates.extend(predicates);
|
||||||
|
generics
|
||||||
|
}
|
||||||
|
|
||||||
// Puts the given bound on any generic type parameters that are used in fields
|
// Puts the given bound on any generic type parameters that are used in fields
|
||||||
// for which filter returns true.
|
// for which filter returns true.
|
||||||
//
|
//
|
||||||
|
|||||||
+275
-156
File diff suppressed because it is too large
Load Diff
@@ -6,11 +6,11 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use attr;
|
use internals::attr;
|
||||||
use check;
|
use internals::check;
|
||||||
|
use internals::Ctxt;
|
||||||
use syn;
|
use syn;
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use Ctxt;
|
|
||||||
|
|
||||||
pub struct Container<'a> {
|
pub struct Container<'a> {
|
||||||
pub ident: syn::Ident,
|
pub ident: syn::Ident,
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
use internals::Ctxt;
|
||||||
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
@@ -15,7 +16,6 @@ use syn::synom::{ParseError, Synom};
|
|||||||
use syn::Ident;
|
use syn::Ident;
|
||||||
use syn::Meta::{List, NameValue, Word};
|
use syn::Meta::{List, NameValue, Word};
|
||||||
use syn::NestedMeta::{Literal, Meta};
|
use syn::NestedMeta::{Literal, Meta};
|
||||||
use Ctxt;
|
|
||||||
|
|
||||||
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
||||||
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
|
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
|
||||||
@@ -25,7 +25,7 @@ use Ctxt;
|
|||||||
// user will see errors simultaneously for all bad attributes in the crate
|
// user will see errors simultaneously for all bad attributes in the crate
|
||||||
// rather than just the first.
|
// rather than just the first.
|
||||||
|
|
||||||
pub use case::RenameRule;
|
pub use internals::case::RenameRule;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct Attr<'c, T> {
|
struct Attr<'c, T> {
|
||||||
@@ -167,6 +167,7 @@ pub enum Identifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Identifier {
|
impl Identifier {
|
||||||
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
pub fn is_some(self) -> bool {
|
pub fn is_some(self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Identifier::No => false,
|
Identifier::No => false,
|
||||||
@@ -526,6 +527,8 @@ pub struct Variant {
|
|||||||
ser_renamed: bool,
|
ser_renamed: bool,
|
||||||
de_renamed: bool,
|
de_renamed: bool,
|
||||||
rename_all: RenameRule,
|
rename_all: RenameRule,
|
||||||
|
ser_bound: Option<Vec<syn::WherePredicate>>,
|
||||||
|
de_bound: Option<Vec<syn::WherePredicate>>,
|
||||||
skip_deserializing: bool,
|
skip_deserializing: bool,
|
||||||
skip_serializing: bool,
|
skip_serializing: bool,
|
||||||
other: bool,
|
other: bool,
|
||||||
@@ -541,6 +544,8 @@ impl Variant {
|
|||||||
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
|
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
|
||||||
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
|
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
|
||||||
let mut rename_all = Attr::none(cx, "rename_all");
|
let mut rename_all = Attr::none(cx, "rename_all");
|
||||||
|
let mut ser_bound = Attr::none(cx, "bound");
|
||||||
|
let mut de_bound = Attr::none(cx, "bound");
|
||||||
let mut other = BoolAttr::none(cx, "other");
|
let mut other = BoolAttr::none(cx, "other");
|
||||||
let mut serialize_with = Attr::none(cx, "serialize_with");
|
let mut serialize_with = Attr::none(cx, "serialize_with");
|
||||||
let mut deserialize_with = Attr::none(cx, "deserialize_with");
|
let mut deserialize_with = Attr::none(cx, "deserialize_with");
|
||||||
@@ -579,6 +584,12 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse `#[serde(skip)]`
|
||||||
|
Meta(Word(word)) if word == "skip" => {
|
||||||
|
skip_serializing.set_true();
|
||||||
|
skip_deserializing.set_true();
|
||||||
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_deserializing)]`
|
// Parse `#[serde(skip_deserializing)]`
|
||||||
Meta(Word(word)) if word == "skip_deserializing" => {
|
Meta(Word(word)) if word == "skip_deserializing" => {
|
||||||
skip_deserializing.set_true();
|
skip_deserializing.set_true();
|
||||||
@@ -594,6 +605,24 @@ impl Variant {
|
|||||||
other.set_true();
|
other.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse `#[serde(bound = "D: Serialize")]`
|
||||||
|
Meta(NameValue(ref m)) if m.ident == "bound" => {
|
||||||
|
if let Ok(where_predicates) =
|
||||||
|
parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
|
||||||
|
{
|
||||||
|
ser_bound.set(where_predicates.clone());
|
||||||
|
de_bound.set(where_predicates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
|
||||||
|
Meta(List(ref m)) if m.ident == "bound" => {
|
||||||
|
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
|
||||||
|
ser_bound.set_opt(ser);
|
||||||
|
de_bound.set_opt(de);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse `#[serde(with = "...")]`
|
// Parse `#[serde(with = "...")]`
|
||||||
Meta(NameValue(ref m)) if m.ident == "with" => {
|
Meta(NameValue(ref m)) if m.ident == "with" => {
|
||||||
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
|
if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
|
||||||
@@ -662,6 +691,8 @@ impl Variant {
|
|||||||
ser_renamed: ser_renamed,
|
ser_renamed: ser_renamed,
|
||||||
de_renamed: de_renamed,
|
de_renamed: de_renamed,
|
||||||
rename_all: rename_all.get().unwrap_or(RenameRule::None),
|
rename_all: rename_all.get().unwrap_or(RenameRule::None),
|
||||||
|
ser_bound: ser_bound.get(),
|
||||||
|
de_bound: de_bound.get(),
|
||||||
skip_deserializing: skip_deserializing.get(),
|
skip_deserializing: skip_deserializing.get(),
|
||||||
skip_serializing: skip_serializing.get(),
|
skip_serializing: skip_serializing.get(),
|
||||||
other: other.get(),
|
other: other.get(),
|
||||||
@@ -688,6 +719,14 @@ impl Variant {
|
|||||||
&self.rename_all
|
&self.rename_all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
|
||||||
|
self.ser_bound.as_ref().map(|vec| &vec[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
|
||||||
|
self.de_bound.as_ref().map(|vec| &vec[..])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn skip_deserializing(&self) -> bool {
|
pub fn skip_deserializing(&self) -> bool {
|
||||||
self.skip_deserializing
|
self.skip_deserializing
|
||||||
}
|
}
|
||||||
@@ -737,6 +776,16 @@ pub enum Default {
|
|||||||
Path(syn::ExprPath),
|
Path(syn::ExprPath),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default {
|
||||||
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
|
pub fn is_none(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
Default::None => true,
|
||||||
|
Default::Default | Default::Path(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Field {
|
impl Field {
|
||||||
/// Extract out the `#[serde(...)]` attributes from a struct field.
|
/// Extract out the `#[serde(...)]` attributes from a struct field.
|
||||||
pub fn from_ast(
|
pub fn from_ast(
|
||||||
@@ -766,9 +815,7 @@ impl Field {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let variant_borrow = attrs
|
let variant_borrow = attrs
|
||||||
.map(|variant| &variant.borrow)
|
.and_then(|variant| variant.borrow.as_ref())
|
||||||
.unwrap_or(&None)
|
|
||||||
.as_ref()
|
|
||||||
.map(|borrow| vec![Meta(borrow.clone())]);
|
.map(|borrow| vec![Meta(borrow.clone())]);
|
||||||
|
|
||||||
for meta_items in field
|
for meta_items in field
|
||||||
@@ -991,7 +1038,7 @@ impl Field {
|
|||||||
};
|
};
|
||||||
deserialize_with.set_if_none(expr);
|
deserialize_with.set_if_none(expr);
|
||||||
}
|
}
|
||||||
} else if is_rptr(&field.ty, is_str) || is_rptr(&field.ty, is_slice_u8) {
|
} else if is_implicitly_borrowed(&field.ty) {
|
||||||
// Types &str and &[u8] are always implicitly borrowed. No need for
|
// Types &str and &[u8] are always implicitly borrowed. No need for
|
||||||
// a #[serde(borrow)].
|
// a #[serde(borrow)].
|
||||||
collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
|
collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
|
||||||
@@ -1253,6 +1300,14 @@ fn parse_lit_into_lifetimes(
|
|||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
|
||||||
|
is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
|
||||||
|
is_reference(ty, is_str) || is_reference(ty, is_slice_u8)
|
||||||
|
}
|
||||||
|
|
||||||
// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
|
// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
|
||||||
// This can have false negatives and false positives.
|
// This can have false negatives and false positives.
|
||||||
//
|
//
|
||||||
@@ -1300,6 +1355,31 @@ fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||||
|
let path = match *ty {
|
||||||
|
syn::Type::Path(ref ty) => &ty.path,
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let seg = match path.segments.last() {
|
||||||
|
Some(seg) => seg.into_value(),
|
||||||
|
None => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let args = match seg.arguments {
|
||||||
|
syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
|
||||||
|
_ => {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
seg.ident == "Option" && args.len() == 1 && match args[0] {
|
||||||
|
syn::GenericArgument::Type(ref arg) => elem(arg),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Whether the type looks like it might be `&T` where elem="T". This can have
|
// Whether the type looks like it might be `&T` where elem="T". This can have
|
||||||
// false negatives and false positives.
|
// false negatives and false positives.
|
||||||
//
|
//
|
||||||
@@ -1320,7 +1400,7 @@ fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
|||||||
// struct S<'a> {
|
// struct S<'a> {
|
||||||
// r: &'a str,
|
// r: &'a str,
|
||||||
// }
|
// }
|
||||||
fn is_rptr(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||||
match *ty {
|
match *ty {
|
||||||
syn::Type::Reference(ref ty) => ty.mutability.is_none() && elem(&ty.elem),
|
syn::Type::Reference(ref ty) => ty.mutability.is_none() && elem(&ty.elem),
|
||||||
_ => false,
|
_ => false,
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use ast::{Container, Data, Style};
|
use internals::ast::{Container, Data, Field, Style};
|
||||||
use attr::{EnumTag, Identifier};
|
use internals::attr::{EnumTag, Identifier};
|
||||||
use Ctxt;
|
use internals::Ctxt;
|
||||||
|
|
||||||
/// Cross-cutting checks that require looking at more than a single attrs
|
/// Cross-cutting checks that require looking at more than a single attrs
|
||||||
/// object. Simpler checks should happen when parsing and building the attrs.
|
/// object. Simpler checks should happen when parsing and building the attrs.
|
||||||
@@ -44,43 +44,49 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
|
|||||||
/// Flattening has some restrictions we can test.
|
/// Flattening has some restrictions we can test.
|
||||||
fn check_flatten(cx: &Ctxt, cont: &Container) {
|
fn check_flatten(cx: &Ctxt, cont: &Container) {
|
||||||
match cont.data {
|
match cont.data {
|
||||||
Data::Enum(_) => {
|
Data::Enum(ref variants) => {
|
||||||
if cont.attrs.has_flatten() {
|
for variant in variants {
|
||||||
cx.error("#[serde(flatten)] cannot be used within enums");
|
for field in &variant.fields {
|
||||||
}
|
check_flatten_field(cx, variant.style, field);
|
||||||
}
|
|
||||||
Data::Struct(style, _) => {
|
|
||||||
for field in cont.data.all_fields() {
|
|
||||||
if !field.attrs.flatten() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
match style {
|
|
||||||
Style::Tuple => {
|
|
||||||
cx.error("#[serde(flatten)] cannot be used on tuple structs");
|
|
||||||
}
|
|
||||||
Style::Newtype => {
|
|
||||||
cx.error("#[serde(flatten)] cannot be used on newtype structs");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
if field.attrs.skip_serializing() {
|
|
||||||
cx.error(
|
|
||||||
"#[serde(flatten] can not be combined with \
|
|
||||||
#[serde(skip_serializing)]",
|
|
||||||
);
|
|
||||||
} else if field.attrs.skip_serializing_if().is_some() {
|
|
||||||
cx.error(
|
|
||||||
"#[serde(flatten] can not be combined with \
|
|
||||||
#[serde(skip_serializing_if = \"...\")]",
|
|
||||||
);
|
|
||||||
} else if field.attrs.skip_deserializing() {
|
|
||||||
cx.error(
|
|
||||||
"#[serde(flatten] can not be combined with \
|
|
||||||
#[serde(skip_deserializing)]",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Data::Struct(style, ref fields) => {
|
||||||
|
for field in fields {
|
||||||
|
check_flatten_field(cx, style, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
|
||||||
|
if !field.attrs.flatten() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
match style {
|
||||||
|
Style::Tuple => {
|
||||||
|
cx.error("#[serde(flatten)] cannot be used on tuple structs");
|
||||||
|
}
|
||||||
|
Style::Newtype => {
|
||||||
|
cx.error("#[serde(flatten)] cannot be used on newtype structs");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
if field.attrs.skip_serializing() {
|
||||||
|
cx.error(
|
||||||
|
"#[serde(flatten] can not be combined with \
|
||||||
|
#[serde(skip_serializing)]",
|
||||||
|
);
|
||||||
|
} else if field.attrs.skip_serializing_if().is_some() {
|
||||||
|
cx.error(
|
||||||
|
"#[serde(flatten] can not be combined with \
|
||||||
|
#[serde(skip_serializing_if = \"...\")]",
|
||||||
|
);
|
||||||
|
} else if field.attrs.skip_deserializing() {
|
||||||
|
cx.error(
|
||||||
|
"#[serde(flatten] can not be combined with \
|
||||||
|
#[serde(skip_deserializing)]",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2017 Serde Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
pub mod ast;
|
||||||
|
pub mod attr;
|
||||||
|
|
||||||
|
mod ctxt;
|
||||||
|
pub use self::ctxt::Ctxt;
|
||||||
|
|
||||||
|
mod case;
|
||||||
|
mod check;
|
||||||
+19
-12
@@ -22,10 +22,23 @@
|
|||||||
//!
|
//!
|
||||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.40")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.57")]
|
||||||
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(
|
#![cfg_attr(
|
||||||
feature = "cargo-clippy",
|
feature = "cargo-clippy",
|
||||||
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
|
allow(
|
||||||
|
enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding,
|
||||||
|
cyclomatic_complexity
|
||||||
|
)
|
||||||
|
)]
|
||||||
|
// Whitelisted clippy_pedantic lints
|
||||||
|
#![cfg_attr(
|
||||||
|
feature = "cargo-clippy",
|
||||||
|
allow(
|
||||||
|
items_after_statements, doc_markdown, stutter, similar_names, use_self, single_match_else,
|
||||||
|
enum_glob_use, match_same_arms, filter_map, cast_possible_truncation
|
||||||
|
)
|
||||||
)]
|
)]
|
||||||
// The `quote!` macro requires deep recursion.
|
// The `quote!` macro requires deep recursion.
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
@@ -35,29 +48,23 @@ extern crate quote;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
|
|
||||||
extern crate serde_derive_internals as internals;
|
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate proc_macro2;
|
extern crate proc_macro2;
|
||||||
|
|
||||||
|
mod internals;
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use syn::DeriveInput;
|
use syn::DeriveInput;
|
||||||
|
|
||||||
// Quote's default is def_site but it appears call_site is likely to stabilize
|
|
||||||
// before def_site. Thus we try to use only call_site.
|
|
||||||
macro_rules! quote {
|
|
||||||
($($tt:tt)*) => {
|
|
||||||
quote_spanned!($crate::proc_macro2::Span::call_site()=> $($tt)*)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod bound;
|
mod bound;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod fragment;
|
mod fragment;
|
||||||
|
|
||||||
mod de;
|
mod de;
|
||||||
|
mod pretend;
|
||||||
mod ser;
|
mod ser;
|
||||||
|
mod try;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
use proc_macro2::Span;
|
||||||
|
use quote::Tokens;
|
||||||
|
use syn::Ident;
|
||||||
|
|
||||||
|
use internals::ast::{Container, Data, Field, Style};
|
||||||
|
|
||||||
|
// Suppress dead_code warnings that would otherwise appear when using a remote
|
||||||
|
// derive. Other than this pretend code, a struct annotated with remote derive
|
||||||
|
// never has its fields referenced and an enum annotated with remote derive
|
||||||
|
// never has its variants constructed.
|
||||||
|
//
|
||||||
|
// warning: field is never used: `i`
|
||||||
|
// --> src/main.rs:4:20
|
||||||
|
// |
|
||||||
|
// 4 | struct StructDef { i: i32 }
|
||||||
|
// | ^^^^^^
|
||||||
|
//
|
||||||
|
// warning: variant is never constructed: `V`
|
||||||
|
// --> src/main.rs:8:16
|
||||||
|
// |
|
||||||
|
// 8 | enum EnumDef { V }
|
||||||
|
// | ^
|
||||||
|
//
|
||||||
|
pub fn pretend_used(cont: &Container) -> Tokens {
|
||||||
|
let pretend_fields = pretend_fields_used(cont);
|
||||||
|
let pretend_variants = pretend_variants_used(cont);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#pretend_fields
|
||||||
|
#pretend_variants
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For structs with named fields, expands to:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T { a: ref __v0, b: ref __v1 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// For enums, expands to the following but only including struct variants:
|
||||||
|
//
|
||||||
|
// match None::<T> {
|
||||||
|
// Some(T::A { a: ref __v0 }) => {}
|
||||||
|
// Some(T::B { b: ref __v0 }) => {}
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The `ref` is important in case the user has written a Drop impl on their
|
||||||
|
// type. Rust does not allow destructuring a struct or enum that has a Drop
|
||||||
|
// impl.
|
||||||
|
fn pretend_fields_used(cont: &Container) -> Tokens {
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
|
||||||
|
let patterns = match cont.data {
|
||||||
|
Data::Enum(ref variants) => variants
|
||||||
|
.iter()
|
||||||
|
.filter_map(|variant| match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let pat = struct_pattern(&variant.fields);
|
||||||
|
Some(quote!(#type_ident::#variant_ident #pat))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
Data::Struct(Style::Struct, ref fields) => {
|
||||||
|
let pat = struct_pattern(fields);
|
||||||
|
vec![quote!(#type_ident #pat)]
|
||||||
|
}
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None::<#type_ident #ty_generics> {
|
||||||
|
#(
|
||||||
|
_serde::export::Some(#patterns) => {}
|
||||||
|
)*
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expands to one of these per enum variant:
|
||||||
|
//
|
||||||
|
// match None {
|
||||||
|
// Some((__v0, __v1,)) => {
|
||||||
|
// let _ = E::V { a: __v0, b: __v1 };
|
||||||
|
// }
|
||||||
|
// _ => {}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
fn pretend_variants_used(cont: &Container) -> Tokens {
|
||||||
|
let variants = match cont.data {
|
||||||
|
Data::Enum(ref variants) => variants,
|
||||||
|
Data::Struct(_, _) => {
|
||||||
|
return quote!();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let type_ident = cont.ident;
|
||||||
|
let (_, ty_generics, _) = cont.generics.split_for_impl();
|
||||||
|
let turbofish = ty_generics.as_turbofish();
|
||||||
|
|
||||||
|
let cases = variants.iter().map(|variant| {
|
||||||
|
let variant_ident = variant.ident;
|
||||||
|
let placeholders = &(0..variant.fields.len())
|
||||||
|
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let pat = match variant.style {
|
||||||
|
Style::Struct => {
|
||||||
|
let names = variant.fields.iter().map(|field| field.ident);
|
||||||
|
quote!({ #(#names: #placeholders),* })
|
||||||
|
}
|
||||||
|
Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )),
|
||||||
|
Style::Unit => quote!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
match _serde::export::None {
|
||||||
|
_serde::export::Some((#(#placeholders,)*)) => {
|
||||||
|
let _ = #type_ident::#variant_ident #turbofish #pat;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
quote!(#(#cases)*)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn struct_pattern(fields: &[Field]) -> Tokens {
|
||||||
|
let names = fields.iter().map(|field| field.ident);
|
||||||
|
let placeholders =
|
||||||
|
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
|
||||||
|
quote!({ #(#names: ref #placeholders),* })
|
||||||
|
}
|
||||||
+174
-29
@@ -15,8 +15,8 @@ use bound;
|
|||||||
use fragment::{Fragment, Match, Stmts};
|
use fragment::{Fragment, Match, Stmts};
|
||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, Ctxt};
|
use internals::{attr, Ctxt};
|
||||||
|
use pretend;
|
||||||
use std::u32;
|
use try;
|
||||||
|
|
||||||
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
|
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
|
||||||
let ctxt = Ctxt::new();
|
let ctxt = Ctxt::new();
|
||||||
@@ -24,7 +24,7 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
precondition(&ctxt, &cont);
|
precondition(&ctxt, &cont);
|
||||||
try!(ctxt.check());
|
try!(ctxt.check());
|
||||||
|
|
||||||
let ident = &cont.ident;
|
let ident = cont.ident;
|
||||||
let params = Parameters::new(&cont);
|
let params = Parameters::new(&cont);
|
||||||
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
|
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
|
||||||
@@ -32,12 +32,14 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
|
|
||||||
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
let impl_block = if let Some(remote) = cont.attrs.remote() {
|
||||||
let vis = &input.vis;
|
let vis = &input.vis;
|
||||||
let fun = quote_spanned!(Span::call_site()=> serialize);
|
let used = pretend::pretend_used(&cont);
|
||||||
quote! {
|
quote! {
|
||||||
impl #impl_generics #ident #ty_generics #where_clause {
|
impl #impl_generics #ident #ty_generics #where_clause {
|
||||||
#vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where
|
||||||
|
__S: _serde::Serializer,
|
||||||
{
|
{
|
||||||
|
#used
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +49,8 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
#[automatically_derived]
|
#[automatically_derived]
|
||||||
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
|
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
|
||||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where
|
||||||
|
__S: _serde::Serializer,
|
||||||
{
|
{
|
||||||
#body
|
#body
|
||||||
}
|
}
|
||||||
@@ -55,10 +58,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let try_replacement = try::replacement();
|
||||||
let generated = quote! {
|
let generated = 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;
|
||||||
|
#try_replacement
|
||||||
#impl_block
|
#impl_block
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -133,6 +138,9 @@ fn build_generics(cont: &Container) -> syn::Generics {
|
|||||||
let generics =
|
let generics =
|
||||||
bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound);
|
bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound);
|
||||||
|
|
||||||
|
let generics =
|
||||||
|
bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::ser_bound);
|
||||||
|
|
||||||
match cont.attrs.ser_bound() {
|
match cont.attrs.ser_bound() {
|
||||||
Some(predicates) => bound::with_where_predicates(&generics, predicates),
|
Some(predicates) => bound::with_where_predicates(&generics, predicates),
|
||||||
None => bound::with_bound(
|
None => bound::with_bound(
|
||||||
@@ -145,13 +153,16 @@ fn build_generics(cont: &Container) -> syn::Generics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fields with a `skip_serializing` or `serialize_with` attribute, or which
|
// Fields with a `skip_serializing` or `serialize_with` attribute, or which
|
||||||
// belong to a variant with a `serialize_with` attribute, are not serialized by
|
// belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
|
||||||
// us so we do not generate a bound. Fields with a `bound` attribute specify
|
// are not serialized by us so we do not generate a bound. Fields with a `bound`
|
||||||
// their own bound so we do not generate one. All other fields may need a `T:
|
// attribute specify their own bound so we do not generate one. All other fields
|
||||||
// Serialize` bound where T is the type of the field.
|
// may need a `T: Serialize` bound where T is the type of the field.
|
||||||
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
|
||||||
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
|
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
|
||||||
&& variant.map_or(true, |variant| variant.serialize_with().is_none())
|
&& variant.map_or(true, |variant| {
|
||||||
|
!variant.skip_serializing() && variant.serialize_with().is_none()
|
||||||
|
&& variant.ser_bound().is_none()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
||||||
@@ -181,7 +192,7 @@ fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
|
fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
|
||||||
let self_var = ¶ms.self_var;
|
let self_var = params.self_var;
|
||||||
quote_block! {
|
quote_block! {
|
||||||
_serde::Serialize::serialize(
|
_serde::Serialize::serialize(
|
||||||
&_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
|
&_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
|
||||||
@@ -232,8 +243,28 @@ fn serialize_tuple_struct(
|
|||||||
serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct);
|
serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct);
|
||||||
|
|
||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
let len = serialize_stmts.len();
|
|
||||||
let let_mut = mut_if(len > 0);
|
let mut serialized_fields = fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||||
|
|
||||||
|
let len = serialized_fields
|
||||||
|
.map(|(i, field)| match field.attrs.skip_serializing_if() {
|
||||||
|
None => quote!(1),
|
||||||
|
Some(path) => {
|
||||||
|
let index = syn::Index {
|
||||||
|
index: i as u32,
|
||||||
|
span: Span::call_site(),
|
||||||
|
};
|
||||||
|
let field_expr = get_member(params, field, &Member::Unnamed(index));
|
||||||
|
quote!(if #path(#field_expr) { 0 } else { 1 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
|
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
|
||||||
@@ -243,7 +274,7 @@ fn serialize_tuple_struct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
|
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
|
||||||
assert!(fields.len() as u64 <= u64::from(u32::MAX));
|
assert!(fields.len() as u64 <= u64::from(u32::max_value()));
|
||||||
|
|
||||||
if cattrs.has_flatten() {
|
if cattrs.has_flatten() {
|
||||||
serialize_struct_as_map(params, fields, cattrs)
|
serialize_struct_as_map(params, fields, cattrs)
|
||||||
@@ -326,9 +357,9 @@ fn serialize_struct_as_map(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
|
fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
|
||||||
assert!(variants.len() as u64 <= u64::from(u32::MAX));
|
assert!(variants.len() as u64 <= u64::from(u32::max_value()));
|
||||||
|
|
||||||
let self_var = ¶ms.self_var;
|
let self_var = params.self_var;
|
||||||
|
|
||||||
let arms: Vec<_> = variants
|
let arms: Vec<_> = variants
|
||||||
.iter()
|
.iter()
|
||||||
@@ -594,9 +625,15 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
quote_expr! {
|
return quote_block! {
|
||||||
_serde::Serialize::serialize(#field_expr, __serializer)
|
let mut __struct = try!(_serde::Serializer::serialize_struct(
|
||||||
}
|
__serializer, #type_name, 2));
|
||||||
|
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||||
|
&mut __struct, #tag, #variant_name));
|
||||||
|
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||||
|
&mut __struct, #content, #field_expr));
|
||||||
|
_serde::ser::SerializeStruct::end(__struct)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Style::Tuple => {
|
Style::Tuple => {
|
||||||
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
|
||||||
@@ -632,7 +669,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
|
|
||||||
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
|
|
||||||
let wrapper_generics = if let Style::Unit = variant.style {
|
let wrapper_generics = if fields_ident.is_empty() {
|
||||||
params.generics.clone()
|
params.generics.clone()
|
||||||
} else {
|
} else {
|
||||||
bound::with_lifetime_bound(¶ms.generics, "'__a")
|
bound::with_lifetime_bound(¶ms.generics, "'__a")
|
||||||
@@ -647,7 +684,8 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
|
|
||||||
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
||||||
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where
|
||||||
|
__S: _serde::Serializer,
|
||||||
{
|
{
|
||||||
let (#(#fields_ident,)*) = self.data;
|
let (#(#fields_ident,)*) = self.data;
|
||||||
#inner
|
#inner
|
||||||
@@ -725,8 +763,23 @@ fn serialize_tuple_variant(
|
|||||||
|
|
||||||
let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);
|
let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);
|
||||||
|
|
||||||
let len = serialize_stmts.len();
|
let mut serialized_fields = fields
|
||||||
let let_mut = mut_if(len > 0);
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||||
|
|
||||||
|
let len = serialized_fields
|
||||||
|
.map(|(i, field)| match field.attrs.skip_serializing_if() {
|
||||||
|
None => quote!(1),
|
||||||
|
Some(path) => {
|
||||||
|
let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
|
||||||
|
quote!(if #path(#field_expr) { 0 } else { 1 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
|
||||||
|
|
||||||
match context {
|
match context {
|
||||||
TupleVariant::ExternallyTagged {
|
TupleVariant::ExternallyTagged {
|
||||||
@@ -775,6 +828,10 @@ fn serialize_struct_variant<'a>(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
|
if fields.iter().any(|field| field.attrs.flatten()) {
|
||||||
|
return serialize_struct_variant_with_flatten(context, params, fields, name);
|
||||||
|
}
|
||||||
|
|
||||||
let struct_trait = match context {
|
let struct_trait = match context {
|
||||||
StructVariant::ExternallyTagged { .. } => (StructTrait::SerializeStructVariant),
|
StructVariant::ExternallyTagged { .. } => (StructTrait::SerializeStructVariant),
|
||||||
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => {
|
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => {
|
||||||
@@ -849,6 +906,92 @@ fn serialize_struct_variant<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_struct_variant_with_flatten<'a>(
|
||||||
|
context: StructVariant<'a>,
|
||||||
|
params: &Parameters,
|
||||||
|
fields: &[Field],
|
||||||
|
name: &str,
|
||||||
|
) -> Fragment {
|
||||||
|
let struct_trait = StructTrait::SerializeMap;
|
||||||
|
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
|
||||||
|
|
||||||
|
let mut serialized_fields = fields
|
||||||
|
.iter()
|
||||||
|
.filter(|&field| !field.attrs.skip_serializing())
|
||||||
|
.peekable();
|
||||||
|
|
||||||
|
let let_mut = mut_if(serialized_fields.peek().is_some());
|
||||||
|
|
||||||
|
match context {
|
||||||
|
StructVariant::ExternallyTagged {
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
} => {
|
||||||
|
let this = ¶ms.this;
|
||||||
|
let fields_ty = fields.iter().map(|f| &f.ty);
|
||||||
|
let fields_ident = &fields.iter().map(|f| f.ident).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
|
let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a");
|
||||||
|
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
|
||||||
|
|
||||||
|
quote_block! {
|
||||||
|
struct __EnumFlatten #wrapper_generics #where_clause {
|
||||||
|
data: (#(&'__a #fields_ty,)*),
|
||||||
|
phantom: _serde::export::PhantomData<#this #ty_generics>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
|
||||||
|
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
|
where
|
||||||
|
__S: _serde::Serializer,
|
||||||
|
{
|
||||||
|
let (#(#fields_ident,)*) = self.data;
|
||||||
|
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||||
|
__serializer,
|
||||||
|
_serde::export::None));
|
||||||
|
#(#serialize_fields)*
|
||||||
|
_serde::ser::SerializeMap::end(__serde_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_serde::Serializer::serialize_newtype_variant(
|
||||||
|
__serializer,
|
||||||
|
#name,
|
||||||
|
#variant_index,
|
||||||
|
#variant_name,
|
||||||
|
&__EnumFlatten {
|
||||||
|
data: (#(#fields_ident,)*),
|
||||||
|
phantom: _serde::export::PhantomData::<#this #ty_generics>,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StructVariant::InternallyTagged { tag, variant_name } => {
|
||||||
|
quote_block! {
|
||||||
|
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||||
|
__serializer,
|
||||||
|
_serde::export::None));
|
||||||
|
try!(_serde::ser::SerializeMap::serialize_entry(
|
||||||
|
&mut __serde_state,
|
||||||
|
#tag,
|
||||||
|
#variant_name,
|
||||||
|
));
|
||||||
|
#(#serialize_fields)*
|
||||||
|
_serde::ser::SerializeMap::end(__serde_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StructVariant::Untagged => {
|
||||||
|
quote_block! {
|
||||||
|
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
|
||||||
|
__serializer,
|
||||||
|
_serde::export::None));
|
||||||
|
#(#serialize_fields)*
|
||||||
|
_serde::ser::SerializeMap::end(__serde_state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn serialize_tuple_struct_visitor(
|
fn serialize_tuple_struct_visitor(
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
@@ -858,6 +1001,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
.filter(|&(_, ref field)| !field.attrs.skip_serializing())
|
||||||
.map(|(i, field)| {
|
.map(|(i, field)| {
|
||||||
let mut field_expr = if is_enum {
|
let mut field_expr = if is_enum {
|
||||||
let id = Ident::new(&format!("__field{}", i), Span::call_site());
|
let id = Ident::new(&format!("__field{}", i), Span::call_site());
|
||||||
@@ -1026,7 +1170,8 @@ fn wrap_serialize_with(
|
|||||||
|
|
||||||
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
||||||
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
|
||||||
where __S: _serde::Serializer
|
where
|
||||||
|
__S: _serde::Serializer,
|
||||||
{
|
{
|
||||||
#serialize_with(#(self.values.#field_access, )* __s)
|
#serialize_with(#(self.values.#field_access, )* __s)
|
||||||
}
|
}
|
||||||
@@ -1054,11 +1199,11 @@ fn mut_if(is_mut: bool) -> Option<Tokens> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
|
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
|
||||||
let self_var = ¶ms.self_var;
|
let self_var = params.self_var;
|
||||||
match (params.is_remote, field.attrs.getter()) {
|
match (params.is_remote, field.attrs.getter()) {
|
||||||
(false, None) => quote_spanned!(Span::call_site()=> &#self_var.#member),
|
(false, None) => quote!(&#self_var.#member),
|
||||||
(true, None) => {
|
(true, None) => {
|
||||||
let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
|
let inner = quote!(&#self_var.#member);
|
||||||
let ty = field.ty;
|
let ty = field.ty;
|
||||||
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
use proc_macro2::{Op, Spacing};
|
||||||
|
use quote::Tokens;
|
||||||
|
|
||||||
|
// None of our generated code requires the `From::from` error conversion
|
||||||
|
// performed by the standard library's `try!` macro. With this simplified macro
|
||||||
|
// we see a significant improvement in type checking and borrow checking time of
|
||||||
|
// the generated code and a slight improvement in binary size.
|
||||||
|
pub fn replacement() -> Tokens {
|
||||||
|
// Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it.
|
||||||
|
let dollar = Op::new('$', Spacing::Alone);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#[allow(unused_macros)]
|
||||||
|
macro_rules! try {
|
||||||
|
(#dollar __expr:expr) => {
|
||||||
|
match #dollar __expr {
|
||||||
|
_serde::export::Ok(__val) => __val,
|
||||||
|
_serde::export::Err(__err) => {
|
||||||
|
return _serde::export::Err(__err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,10 @@ repository = "https://github.com/serde-rs/serde"
|
|||||||
documentation = "https://docs.serde.rs/serde_derive_internals/"
|
documentation = "https://docs.serde.rs/serde_derive_internals/"
|
||||||
keywords = ["serde", "serialization"]
|
keywords = ["serde", "serialization"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "0.3"
|
proc-macro2 = "0.3"
|
||||||
|
|||||||
@@ -17,11 +17,7 @@ extern crate syn;
|
|||||||
|
|
||||||
extern crate proc_macro2;
|
extern crate proc_macro2;
|
||||||
|
|
||||||
pub mod ast;
|
#[path = "src/mod.rs"]
|
||||||
pub mod attr;
|
mod internals;
|
||||||
|
|
||||||
mod ctxt;
|
pub use internals::*;
|
||||||
pub use ctxt::Ctxt;
|
|
||||||
|
|
||||||
mod case;
|
|
||||||
mod check;
|
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../serde_derive/src/internals/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.40" # remember to update html_root_url
|
version = "1.0.57" # remember to update html_root_url
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@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"
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use serde::ser::{SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
use serde::ser::{
|
||||||
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant};
|
SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
|
||||||
|
SerializeTupleStruct, SerializeTupleVariant,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
@@ -24,7 +26,8 @@ pub struct Compact<T: ?Sized>(T);
|
|||||||
///
|
///
|
||||||
/// impl Serialize for Example {
|
/// impl Serialize for Example {
|
||||||
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
/// where S: Serializer,
|
/// where
|
||||||
|
/// S: Serializer,
|
||||||
/// {
|
/// {
|
||||||
/// if serializer.is_human_readable() {
|
/// if serializer.is_human_readable() {
|
||||||
/// format!("{}.{}", self.0, self.1).serialize(serializer)
|
/// format!("{}.{}", self.0, self.1).serialize(serializer)
|
||||||
@@ -36,7 +39,8 @@ pub struct Compact<T: ?Sized>(T);
|
|||||||
///
|
///
|
||||||
/// impl<'de> Deserialize<'de> for Example {
|
/// impl<'de> Deserialize<'de> for Example {
|
||||||
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
/// where D: Deserializer<'de>,
|
/// where
|
||||||
|
/// D: Deserializer<'de>,
|
||||||
/// {
|
/// {
|
||||||
/// use serde::de::Error;
|
/// use serde::de::Error;
|
||||||
/// if deserializer.is_human_readable() {
|
/// if deserializer.is_human_readable() {
|
||||||
@@ -476,7 +480,10 @@ use serde::de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, Varian
|
|||||||
macro_rules! forward_deserialize_methods {
|
macro_rules! forward_deserialize_methods {
|
||||||
( $wrapper : ident ( $( $name: ident ),* ) ) => {
|
( $wrapper : ident ( $( $name: ident ),* ) ) => {
|
||||||
$(
|
$(
|
||||||
fn $name<V>(self, visitor: V) -> Result<V::Value, D::Error> where V: Visitor<'de> {
|
fn $name<V>(self, visitor: V) -> Result<V::Value, D::Error>
|
||||||
|
where
|
||||||
|
V: Visitor<'de>,
|
||||||
|
{
|
||||||
(self.0).$name($wrapper(visitor))
|
(self.0).$name($wrapper(visitor))
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|||||||
@@ -7,8 +7,10 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
|
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
|
||||||
use serde::de::{self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess,
|
use serde::de::{
|
||||||
SeqAccess, VariantAccess, Visitor};
|
self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
|
||||||
|
VariantAccess, Visitor,
|
||||||
|
};
|
||||||
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use token::Token;
|
use token::Token;
|
||||||
|
|||||||
+20
-12
@@ -68,11 +68,13 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! #
|
//! #
|
||||||
//! # impl<K, V> Serialize for LinkedHashMap<K, V>
|
//! # impl<K, V> Serialize for LinkedHashMap<K, V>
|
||||||
//! # where K: Serialize,
|
//! # where
|
||||||
//! # V: Serialize
|
//! # K: Serialize,
|
||||||
|
//! # V: Serialize,
|
||||||
//! # {
|
//! # {
|
||||||
//! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
//! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
//! # where S: Serializer
|
//! # where
|
||||||
|
//! # S: Serializer,
|
||||||
//! # {
|
//! # {
|
||||||
//! # let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
//! # let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
||||||
//! # for &(ref k, ref v) in &self.0 {
|
//! # for &(ref k, ref v) in &self.0 {
|
||||||
@@ -85,8 +87,9 @@
|
|||||||
//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
|
//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
|
||||||
//! #
|
//! #
|
||||||
//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
|
//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
|
||||||
//! # where K: Deserialize<'de>,
|
//! # where
|
||||||
//! # V: Deserialize<'de>
|
//! # K: Deserialize<'de>,
|
||||||
|
//! # V: Deserialize<'de>,
|
||||||
//! # {
|
//! # {
|
||||||
//! # type Value = LinkedHashMap<K, V>;
|
//! # type Value = LinkedHashMap<K, V>;
|
||||||
//! #
|
//! #
|
||||||
@@ -95,7 +98,8 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! #
|
//! #
|
||||||
//! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
//! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||||
//! # where M: MapAccess<'de>
|
//! # where
|
||||||
|
//! # M: MapAccess<'de>,
|
||||||
//! # {
|
//! # {
|
||||||
//! # let mut map = LinkedHashMap::new();
|
//! # let mut map = LinkedHashMap::new();
|
||||||
//! # while let Some((key, value)) = access.next_entry()? {
|
//! # while let Some((key, value)) = access.next_entry()? {
|
||||||
@@ -106,11 +110,13 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! #
|
//! #
|
||||||
//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
|
//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
|
||||||
//! # where K: Deserialize<'de>,
|
//! # where
|
||||||
//! # V: Deserialize<'de>
|
//! # K: Deserialize<'de>,
|
||||||
|
//! # V: Deserialize<'de>,
|
||||||
//! # {
|
//! # {
|
||||||
//! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
//! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
//! # where D: Deserializer<'de>
|
//! # where
|
||||||
|
//! # D: Deserializer<'de>,
|
||||||
//! # {
|
//! # {
|
||||||
//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
|
//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
|
||||||
//! # }
|
//! # }
|
||||||
@@ -155,7 +161,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.40")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.57")]
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||||
// Whitelisted clippy lints
|
// Whitelisted clippy lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
|
||||||
@@ -179,8 +185,10 @@ mod assert;
|
|||||||
mod configure;
|
mod configure;
|
||||||
mod token;
|
mod token;
|
||||||
|
|
||||||
pub use assert::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens,
|
pub use assert::{
|
||||||
assert_ser_tokens_error, assert_tokens};
|
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
|
||||||
|
assert_tokens,
|
||||||
|
};
|
||||||
pub use token::Token;
|
pub use token::Token;
|
||||||
|
|
||||||
pub use configure::{Compact, Configure, Readable};
|
pub use configure::{Compact, Configure, Readable};
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use serde::de::{Deserializer, Visitor, SeqAccess, Error};
|
use serde::de::{Deserializer, Error, SeqAccess, Visitor};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||||
where D: Deserializer<'de>
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
deserializer.deserialize_byte_buf(ByteBufVisitor)
|
deserializer.deserialize_byte_buf(ByteBufVisitor)
|
||||||
}
|
}
|
||||||
@@ -17,7 +18,8 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
||||||
where V: SeqAccess<'de>
|
where
|
||||||
|
V: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
while let Some(value) = try!(visitor.next_element()) {
|
while let Some(value) = try!(visitor.next_element()) {
|
||||||
@@ -27,25 +29,29 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.to_vec())
|
Ok(v.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.as_bytes().to_vec())
|
Ok(v.as_bytes().to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||||
where E: Error
|
where
|
||||||
|
E: Error,
|
||||||
{
|
{
|
||||||
Ok(v.into_bytes())
|
Ok(v.into_bytes())
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-9
@@ -9,13 +9,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
|
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
|
||||||
//~^ HELP: #[serde(flatten)] cannot be used within enums
|
struct S<'de> {
|
||||||
enum Foo {
|
s: &'de str, //~^^ HELP: cannot deserialize when there is a lifetime parameter called 'de
|
||||||
A {
|
|
||||||
#[serde(flatten)]
|
|
||||||
fields: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2018 Serde Developers
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
|
||||||
|
struct S {
|
||||||
|
string: String,
|
||||||
|
slice: [u8], //~^^^ HELP: cannot deserialize a dynamically sized struct
|
||||||
|
}
|
||||||
@@ -12,13 +12,15 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use std::collections::HashMap;
|
|
||||||
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
||||||
use self::serde::de::{self, Unexpected};
|
use self::serde::de::{self, Unexpected};
|
||||||
|
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
extern crate serde_test;
|
extern crate serde_test;
|
||||||
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens,
|
use self::serde_test::{
|
||||||
assert_ser_tokens_error, assert_tokens, Token};
|
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_ser_tokens_error,
|
||||||
|
assert_tokens, Token,
|
||||||
|
};
|
||||||
|
|
||||||
trait MyDefault: Sized {
|
trait MyDefault: Sized {
|
||||||
fn my_default() -> Self;
|
fn my_default() -> Self;
|
||||||
@@ -114,10 +116,7 @@ struct FlattenStructEnumWrapper {
|
|||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
enum FlattenStructEnum {
|
enum FlattenStructEnum {
|
||||||
InsertInteger {
|
InsertInteger { index: u32, value: u32 },
|
||||||
index: u32,
|
|
||||||
value: u32
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -133,10 +132,7 @@ struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum);
|
|||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
||||||
enum FlattenStructTagContentEnum {
|
enum FlattenStructTagContentEnum {
|
||||||
InsertInteger {
|
InsertInteger { index: u32, value: u32 },
|
||||||
index: u32,
|
|
||||||
value: u32
|
|
||||||
},
|
|
||||||
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,12 +525,10 @@ enum RenameEnumSerializeDeserialize<A> {
|
|||||||
fn test_rename_enum() {
|
fn test_rename_enum() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&RenameEnum::Batman,
|
&RenameEnum::Batman,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "Superhero",
|
||||||
name: "Superhero",
|
variant: "bruce_wayne",
|
||||||
variant: "bruce_wayne",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -663,6 +657,44 @@ fn test_skip_serializing_struct() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize)]
|
||||||
|
struct SkipSerializingTupleStruct<'a, B, C>(
|
||||||
|
&'a i8,
|
||||||
|
#[serde(skip_serializing)] B,
|
||||||
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
C: ShouldSkip;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_skip_serializing_tuple_struct() {
|
||||||
|
let a = 1;
|
||||||
|
assert_ser_tokens(
|
||||||
|
&SkipSerializingTupleStruct(&a, 2, 3),
|
||||||
|
&[
|
||||||
|
Token::TupleStruct {
|
||||||
|
name: "SkipSerializingTupleStruct",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
Token::I8(1),
|
||||||
|
Token::I32(3),
|
||||||
|
Token::TupleStructEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ser_tokens(
|
||||||
|
&SkipSerializingTupleStruct(&a, 2, 123),
|
||||||
|
&[
|
||||||
|
Token::TupleStruct {
|
||||||
|
name: "SkipSerializingTupleStruct",
|
||||||
|
len: 1,
|
||||||
|
},
|
||||||
|
Token::I8(1),
|
||||||
|
Token::TupleStructEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
struct SkipStruct<B> {
|
struct SkipStruct<B> {
|
||||||
a: i8,
|
a: i8,
|
||||||
@@ -711,6 +743,11 @@ where
|
|||||||
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
|
||||||
c: C,
|
c: C,
|
||||||
},
|
},
|
||||||
|
Tuple(
|
||||||
|
&'a i8,
|
||||||
|
#[serde(skip_serializing)] B,
|
||||||
|
#[serde(skip_serializing_if = "ShouldSkip::should_skip")] C,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -749,6 +786,33 @@ fn test_skip_serializing_enum() {
|
|||||||
Token::StructVariantEnd,
|
Token::StructVariantEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_ser_tokens(
|
||||||
|
&SkipSerializingEnum::Tuple(&a, 2, 3),
|
||||||
|
&[
|
||||||
|
Token::TupleVariant {
|
||||||
|
name: "SkipSerializingEnum",
|
||||||
|
variant: "Tuple",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
Token::I8(1),
|
||||||
|
Token::I32(3),
|
||||||
|
Token::TupleVariantEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_ser_tokens(
|
||||||
|
&SkipSerializingEnum::Tuple(&a, 2, 123),
|
||||||
|
&[
|
||||||
|
Token::TupleVariant {
|
||||||
|
name: "SkipSerializingEnum",
|
||||||
|
variant: "Tuple",
|
||||||
|
len: 1,
|
||||||
|
},
|
||||||
|
Token::I8(1),
|
||||||
|
Token::TupleVariantEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -1221,12 +1285,7 @@ fn test_missing_renamed_field_enum() {
|
|||||||
#[derive(Debug, PartialEq, Deserialize)]
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
enum InvalidLengthEnum {
|
enum InvalidLengthEnum {
|
||||||
A(i32, i32, i32),
|
A(i32, i32, i32),
|
||||||
B(
|
B(#[serde(skip_deserializing)] i32, i32, i32),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
i32,
|
|
||||||
i32,
|
|
||||||
i32,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1241,7 +1300,7 @@ fn test_invalid_length_enum() {
|
|||||||
Token::I32(1),
|
Token::I32(1),
|
||||||
Token::TupleVariantEnd,
|
Token::TupleVariantEnd,
|
||||||
],
|
],
|
||||||
"invalid length 1, expected tuple of 3 elements",
|
"invalid length 1, expected tuple variant InvalidLengthEnum::A with 3 elements",
|
||||||
);
|
);
|
||||||
assert_de_tokens_error::<InvalidLengthEnum>(
|
assert_de_tokens_error::<InvalidLengthEnum>(
|
||||||
&[
|
&[
|
||||||
@@ -1253,7 +1312,7 @@ fn test_invalid_length_enum() {
|
|||||||
Token::I32(1),
|
Token::I32(1),
|
||||||
Token::TupleVariantEnd,
|
Token::TupleVariantEnd,
|
||||||
],
|
],
|
||||||
"invalid length 1, expected tuple of 2 elements",
|
"invalid length 1, expected tuple variant InvalidLengthEnum::B with 2 elements",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1345,7 +1404,7 @@ fn test_flatten_struct_enum() {
|
|||||||
let change_request = FlattenStructEnumWrapper {
|
let change_request = FlattenStructEnumWrapper {
|
||||||
data: FlattenStructEnum::InsertInteger {
|
data: FlattenStructEnum::InsertInteger {
|
||||||
index: 0,
|
index: 0,
|
||||||
value: 42
|
value: 42,
|
||||||
},
|
},
|
||||||
extra,
|
extra,
|
||||||
};
|
};
|
||||||
@@ -1362,7 +1421,7 @@ fn test_flatten_struct_enum() {
|
|||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
Token::Str("extra_key"),
|
Token::Str("extra_key"),
|
||||||
Token::Str("extra value"),
|
Token::Str("extra value"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
@@ -1370,7 +1429,10 @@ fn test_flatten_struct_enum() {
|
|||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Str("insert_integer"),
|
Token::Str("insert_integer"),
|
||||||
Token::Struct { len: 2, name: "insert_integer" },
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "insert_integer",
|
||||||
|
},
|
||||||
Token::Str("index"),
|
Token::Str("index"),
|
||||||
Token::U32(0),
|
Token::U32(0),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
@@ -1378,7 +1440,7 @@ fn test_flatten_struct_enum() {
|
|||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
Token::Str("extra_key"),
|
Token::Str("extra_key"),
|
||||||
Token::Str("extra value"),
|
Token::Str("extra value"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1387,12 +1449,10 @@ fn test_flatten_struct_enum() {
|
|||||||
fn test_flatten_struct_tag_content_enum() {
|
fn test_flatten_struct_tag_content_enum() {
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
let change_request = FlattenStructTagContentEnumWrapper {
|
||||||
outer: 42,
|
outer: 42,
|
||||||
data: FlattenStructTagContentEnumNewtype(
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger {
|
||||||
FlattenStructTagContentEnum::InsertInteger {
|
index: 0,
|
||||||
index: 0,
|
value: 42,
|
||||||
value: 42
|
}),
|
||||||
}
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&change_request,
|
&change_request,
|
||||||
@@ -1421,7 +1481,10 @@ fn test_flatten_struct_tag_content_enum() {
|
|||||||
Token::Str("type"),
|
Token::Str("type"),
|
||||||
Token::Str("insert_integer"),
|
Token::Str("insert_integer"),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::Struct { len: 2, name: "insert_integer" },
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "insert_integer",
|
||||||
|
},
|
||||||
Token::Str("index"),
|
Token::Str("index"),
|
||||||
Token::U32(0),
|
Token::U32(0),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
@@ -1436,13 +1499,9 @@ fn test_flatten_struct_tag_content_enum() {
|
|||||||
fn test_flatten_struct_tag_content_enum_newtype() {
|
fn test_flatten_struct_tag_content_enum_newtype() {
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
let change_request = FlattenStructTagContentEnumWrapper {
|
||||||
outer: 42,
|
outer: 42,
|
||||||
data: FlattenStructTagContentEnumNewtype(
|
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant(
|
||||||
FlattenStructTagContentEnum::NewtypeVariant(
|
FlattenStructTagContentEnumNewtypeVariant { value: 23 },
|
||||||
FlattenStructTagContentEnumNewtypeVariant {
|
)),
|
||||||
value: 23
|
|
||||||
}
|
|
||||||
)
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&change_request,
|
&change_request,
|
||||||
@@ -1469,7 +1528,10 @@ fn test_flatten_struct_tag_content_enum_newtype() {
|
|||||||
Token::Str("type"),
|
Token::Str("type"),
|
||||||
Token::Str("newtype_variant"),
|
Token::Str("newtype_variant"),
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::Struct { len: 1, name: "FlattenStructTagContentEnumNewtypeVariant" },
|
Token::Struct {
|
||||||
|
len: 1,
|
||||||
|
name: "FlattenStructTagContentEnumNewtypeVariant",
|
||||||
|
},
|
||||||
Token::Str("value"),
|
Token::Str("value"),
|
||||||
Token::U32(23),
|
Token::U32(23),
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
@@ -1525,7 +1587,7 @@ fn test_complex_flatten() {
|
|||||||
first: First,
|
first: First,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
second: Second,
|
second: Second,
|
||||||
z: u32
|
z: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -1552,10 +1614,8 @@ fn test_complex_flatten() {
|
|||||||
d: "c".into(),
|
d: "c".into(),
|
||||||
e: Some(2),
|
e: Some(2),
|
||||||
},
|
},
|
||||||
second: Second {
|
second: Second { f: 3 },
|
||||||
f: 3
|
z: 4,
|
||||||
},
|
|
||||||
z: 4
|
|
||||||
},
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
@@ -1592,10 +1652,8 @@ fn test_complex_flatten() {
|
|||||||
d: "c".into(),
|
d: "c".into(),
|
||||||
e: Some(2),
|
e: Some(2),
|
||||||
},
|
},
|
||||||
second: Second {
|
second: Second { f: 3 },
|
||||||
f: 3
|
z: 4,
|
||||||
},
|
|
||||||
z: 4
|
|
||||||
},
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
@@ -1652,7 +1710,7 @@ fn test_flatten_unsupported_type() {
|
|||||||
Token::Str("foo"),
|
Token::Str("foo"),
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
Token::Str("b"),
|
Token::Str("b"),
|
||||||
Token::MapEnd
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
"can only flatten structs and maps",
|
"can only flatten structs and maps",
|
||||||
);
|
);
|
||||||
@@ -1671,7 +1729,11 @@ fn test_non_string_keys() {
|
|||||||
let mut mapping = HashMap::new();
|
let mut mapping = HashMap::new();
|
||||||
mapping.insert(0, 42);
|
mapping.insert(0, 42);
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&TestStruct { name: "peter".into(), age: 3, mapping },
|
&TestStruct {
|
||||||
|
name: "peter".into(),
|
||||||
|
age: 3,
|
||||||
|
mapping,
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Str("name"),
|
Token::Str("name"),
|
||||||
@@ -1720,7 +1782,9 @@ fn test_lifetime_propagation_for_flatten() {
|
|||||||
let mut borrowed_map = HashMap::new();
|
let mut borrowed_map = HashMap::new();
|
||||||
borrowed_map.insert("x", 42u32);
|
borrowed_map.insert("x", 42u32);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&B { t: borrowed_map.clone() },
|
&B {
|
||||||
|
t: borrowed_map.clone(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::BorrowedStr("x"),
|
Token::BorrowedStr("x"),
|
||||||
@@ -1742,7 +1806,9 @@ fn test_lifetime_propagation_for_flatten() {
|
|||||||
let mut borrowed_map = HashMap::new();
|
let mut borrowed_map = HashMap::new();
|
||||||
borrowed_map.insert(&b"x"[..], 42u32);
|
borrowed_map.insert(&b"x"[..], 42u32);
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&C { t: borrowed_map.clone() },
|
&C {
|
||||||
|
t: borrowed_map.clone(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Seq { len: Some(1) },
|
Token::Seq { len: Some(1) },
|
||||||
@@ -1797,3 +1863,316 @@ fn test_flatten_enum_newtype() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flatten_internally_tagged() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct S {
|
||||||
|
#[serde(flatten)]
|
||||||
|
x: X,
|
||||||
|
#[serde(flatten)]
|
||||||
|
y: Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(tag = "typeX")]
|
||||||
|
enum X {
|
||||||
|
A { a: i32 },
|
||||||
|
B { b: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(tag = "typeY")]
|
||||||
|
enum Y {
|
||||||
|
C { c: i32 },
|
||||||
|
D { d: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
let s = S {
|
||||||
|
x: X::B { b: 1 },
|
||||||
|
y: Y::D { d: 2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&s,
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("typeX"),
|
||||||
|
Token::Str("B"),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(1),
|
||||||
|
Token::Str("typeY"),
|
||||||
|
Token::Str("D"),
|
||||||
|
Token::Str("d"),
|
||||||
|
Token::I32(2),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_externally_tagged_enum_containing_flatten() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
enum Data {
|
||||||
|
A {
|
||||||
|
a: i32,
|
||||||
|
#[serde(flatten)]
|
||||||
|
flat: Flat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Flat {
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Data::A {
|
||||||
|
a: 0,
|
||||||
|
flat: Flat { b: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::NewtypeVariant {
|
||||||
|
name: "Data",
|
||||||
|
variant: "A",
|
||||||
|
},
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_internally_tagged_enum_containing_flatten() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(tag = "t")]
|
||||||
|
enum Data {
|
||||||
|
A {
|
||||||
|
a: i32,
|
||||||
|
#[serde(flatten)]
|
||||||
|
flat: Flat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Flat {
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Data::A {
|
||||||
|
a: 0,
|
||||||
|
flat: Flat { b: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("t"),
|
||||||
|
Token::Str("A"),
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_adjacently_tagged_enum_containing_flatten() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(tag = "t", content = "c")]
|
||||||
|
enum Data {
|
||||||
|
A {
|
||||||
|
a: i32,
|
||||||
|
#[serde(flatten)]
|
||||||
|
flat: Flat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Flat {
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Data::A {
|
||||||
|
a: 0,
|
||||||
|
flat: Flat { b: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::Struct {
|
||||||
|
name: "Data",
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
Token::Str("t"),
|
||||||
|
Token::Str("A"),
|
||||||
|
Token::Str("c"),
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_untagged_enum_containing_flatten() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum Data {
|
||||||
|
A {
|
||||||
|
a: i32,
|
||||||
|
#[serde(flatten)]
|
||||||
|
flat: Flat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Flat {
|
||||||
|
b: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Data::A {
|
||||||
|
a: 0,
|
||||||
|
flat: Flat { b: 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::Str("b"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flatten_untagged_enum() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Outer {
|
||||||
|
#[serde(flatten)]
|
||||||
|
inner: Inner,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum Inner {
|
||||||
|
Variant {
|
||||||
|
a: i32,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = Outer {
|
||||||
|
inner: Inner::Variant {
|
||||||
|
a: 0,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&data,
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_flatten_option() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Outer {
|
||||||
|
#[serde(flatten)]
|
||||||
|
inner1: Option<Inner1>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
inner2: Option<Inner2>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Inner1 {
|
||||||
|
inner1: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
struct Inner2 {
|
||||||
|
inner2: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Outer {
|
||||||
|
inner1: Some(Inner1 {
|
||||||
|
inner1: 1,
|
||||||
|
}),
|
||||||
|
inner2: Some(Inner2 {
|
||||||
|
inner2: 2,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("inner1"),
|
||||||
|
Token::I32(1),
|
||||||
|
Token::Str("inner2"),
|
||||||
|
Token::I32(2),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Outer {
|
||||||
|
inner1: Some(Inner1 {
|
||||||
|
inner1: 1,
|
||||||
|
}),
|
||||||
|
inner2: None,
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("inner1"),
|
||||||
|
Token::I32(1),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Outer {
|
||||||
|
inner1: None,
|
||||||
|
inner2: Some(Inner2 {
|
||||||
|
inner2: 2,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("inner2"),
|
||||||
|
Token::I32(2),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Outer {
|
||||||
|
inner1: None,
|
||||||
|
inner2: None,
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,20 +12,20 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::net;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::ffi::{CString, OsString};
|
use std::ffi::{CString, OsString};
|
||||||
use std::rc::Rc;
|
use std::net;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::rc::{Rc, Weak as RcWeak};
|
||||||
|
use std::sync::{Arc, Weak as ArcWeak};
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use serde::Deserialize;
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
use self::fnv::FnvHasher;
|
use self::fnv::FnvHasher;
|
||||||
@@ -182,6 +182,27 @@ macro_rules! declare_error_tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SkipPartialEq<T>(T);
|
||||||
|
|
||||||
|
impl<'de, T> Deserialize<'de> for SkipPartialEq<T>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
T::deserialize(deserializer).map(SkipPartialEq)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PartialEq for SkipPartialEq<T> {
|
||||||
|
fn eq(&self, _other: &Self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
|
fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
|
||||||
#[derive(PartialEq, Debug, Deserialize)]
|
#[derive(PartialEq, Debug, Deserialize)]
|
||||||
struct IgnoreBase {
|
struct IgnoreBase {
|
||||||
@@ -788,11 +809,33 @@ declare_tests! {
|
|||||||
Token::Bool(true),
|
Token::Bool(true),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_rc_weak_some {
|
||||||
|
SkipPartialEq(RcWeak::<bool>::new()) => &[
|
||||||
|
Token::Some,
|
||||||
|
Token::Bool(true),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_rc_weak_none {
|
||||||
|
SkipPartialEq(RcWeak::<bool>::new()) => &[
|
||||||
|
Token::None,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_arc {
|
test_arc {
|
||||||
Arc::new(true) => &[
|
Arc::new(true) => &[
|
||||||
Token::Bool(true),
|
Token::Bool(true),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_arc_weak_some {
|
||||||
|
SkipPartialEq(ArcWeak::<bool>::new()) => &[
|
||||||
|
Token::Some,
|
||||||
|
Token::Bool(true),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_arc_weak_none {
|
||||||
|
SkipPartialEq(ArcWeak::<bool>::new()) => &[
|
||||||
|
Token::None,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_wrapping {
|
test_wrapping {
|
||||||
Wrapping(1usize) => &[
|
Wrapping(1usize) => &[
|
||||||
Token::U32(1),
|
Token::U32(1),
|
||||||
|
|||||||
+116
-44
@@ -17,8 +17,8 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use self::serde::ser::{Serialize, Serializer};
|
|
||||||
use self::serde::de::{DeserializeOwned, Deserializer};
|
use self::serde::de::{DeserializeOwned, Deserializer};
|
||||||
|
use self::serde::ser::{Serialize, Serializer};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@@ -92,14 +92,10 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EnumWith<T> {
|
enum EnumWith<T> {
|
||||||
Unit,
|
Unit,
|
||||||
Newtype(
|
Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X),
|
||||||
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
|
|
||||||
X,
|
|
||||||
),
|
|
||||||
Tuple(
|
Tuple(
|
||||||
T,
|
T,
|
||||||
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
|
||||||
X,
|
|
||||||
),
|
),
|
||||||
Struct {
|
Struct {
|
||||||
t: T,
|
t: T,
|
||||||
@@ -122,17 +118,13 @@ fn test_gen() {
|
|||||||
assert_ser::<MultipleRef<i32>>();
|
assert_ser::<MultipleRef<i32>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Newtype(
|
struct Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X);
|
||||||
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
|
|
||||||
X,
|
|
||||||
);
|
|
||||||
assert::<Newtype>();
|
assert::<Newtype>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Tuple<T>(
|
struct Tuple<T>(
|
||||||
T,
|
T,
|
||||||
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
|
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
|
||||||
X,
|
|
||||||
);
|
);
|
||||||
assert::<Tuple<i32>>();
|
assert::<Tuple<i32>>();
|
||||||
|
|
||||||
@@ -191,12 +183,16 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(bound = "D: SerializeWith + DeserializeWith")]
|
#[serde(bound = "D: SerializeWith + DeserializeWith")]
|
||||||
struct WithTraits1<D, E> {
|
struct WithTraits1<D, E> {
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with")]
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
d: D,
|
d: D,
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with",
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
bound = "E: SerializeWith + DeserializeWith")]
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound = "E: SerializeWith + DeserializeWith"
|
||||||
|
)]
|
||||||
e: E,
|
e: E,
|
||||||
}
|
}
|
||||||
assert::<WithTraits1<X, X>>();
|
assert::<WithTraits1<X, X>>();
|
||||||
@@ -204,17 +200,58 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
||||||
struct WithTraits2<D, E> {
|
struct WithTraits2<D, E> {
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
deserialize_with = "DeserializeWith::deserialize_with")]
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
d: D,
|
d: D,
|
||||||
#[serde(serialize_with = "SerializeWith::serialize_with",
|
#[serde(
|
||||||
bound(serialize = "E: SerializeWith"))]
|
serialize_with = "SerializeWith::serialize_with", bound(serialize = "E: SerializeWith")
|
||||||
#[serde(deserialize_with = "DeserializeWith::deserialize_with",
|
)]
|
||||||
bound(deserialize = "E: DeserializeWith"))]
|
#[serde(
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound(deserialize = "E: DeserializeWith")
|
||||||
|
)]
|
||||||
e: E,
|
e: E,
|
||||||
}
|
}
|
||||||
assert::<WithTraits2<X, X>>();
|
assert::<WithTraits2<X, X>>();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(bound = "D: SerializeWith + DeserializeWith")]
|
||||||
|
enum VariantWithTraits1<D, E> {
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
|
D(D),
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound = "E: SerializeWith + DeserializeWith"
|
||||||
|
)]
|
||||||
|
E(E),
|
||||||
|
}
|
||||||
|
assert::<VariantWithTraits1<X, X>>();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
|
||||||
|
enum VariantWithTraits2<D, E> {
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "SerializeWith::serialize_with",
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with"
|
||||||
|
)]
|
||||||
|
D(D),
|
||||||
|
#[serde(
|
||||||
|
serialize_with = "SerializeWith::serialize_with", bound(serialize = "E: SerializeWith")
|
||||||
|
)]
|
||||||
|
#[serde(
|
||||||
|
deserialize_with = "DeserializeWith::deserialize_with",
|
||||||
|
bound(deserialize = "E: DeserializeWith")
|
||||||
|
)]
|
||||||
|
E(E),
|
||||||
|
}
|
||||||
|
assert::<VariantWithTraits2<X, X>>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct CowStr<'a>(Cow<'a, str>);
|
struct CowStr<'a>(Cow<'a, str>);
|
||||||
assert::<CowStr>();
|
assert::<CowStr>();
|
||||||
@@ -270,17 +307,11 @@ fn test_gen() {
|
|||||||
struct EmptyTupleDenyUnknown();
|
struct EmptyTupleDenyUnknown();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct TupleSkipAll(
|
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct TupleSkipAllDenyUnknown(
|
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
enum EmptyEnum {}
|
enum EmptyEnum {}
|
||||||
@@ -305,10 +336,7 @@ fn test_gen() {
|
|||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
f: u8,
|
f: u8,
|
||||||
},
|
},
|
||||||
TupleSkip(
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unstable")]
|
#[cfg(feature = "unstable")]
|
||||||
@@ -321,10 +349,7 @@ fn test_gen() {
|
|||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
f: u8,
|
f: u8,
|
||||||
},
|
},
|
||||||
TupleSkip(
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
#[serde(skip_deserializing)]
|
|
||||||
u8,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -344,9 +369,7 @@ fn test_gen() {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(untagged, remote = "Or")]
|
#[serde(untagged, remote = "Or")]
|
||||||
enum OrDef<A, B> {
|
enum OrDef<A, B> {
|
||||||
#[allow(dead_code)]
|
|
||||||
A(A),
|
A(A),
|
||||||
#[allow(dead_code)]
|
|
||||||
B(B),
|
B(B),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,6 +526,13 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
assert_ser::<UntaggedVariantWith>();
|
assert_ser::<UntaggedVariantWith>();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct FlattenWith {
|
||||||
|
#[serde(flatten, serialize_with = "ser_x", deserialize_with = "de_x")]
|
||||||
|
x: X,
|
||||||
|
}
|
||||||
|
assert::<FlattenWith>();
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct StaticStrStruct<'a> {
|
struct StaticStrStruct<'a> {
|
||||||
a: &'a str,
|
a: &'a str,
|
||||||
@@ -531,7 +561,9 @@ fn test_gen() {
|
|||||||
assert::<SkippedStaticStr>();
|
assert::<SkippedStaticStr>();
|
||||||
|
|
||||||
macro_rules! T {
|
macro_rules! T {
|
||||||
() => { () }
|
() => {
|
||||||
|
()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -559,7 +591,7 @@ fn test_gen() {
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct AssocDerive<T: AssocSerde> {
|
struct AssocDerive<T: AssocSerde> {
|
||||||
assoc: T::Assoc
|
assoc: T::Assoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert::<AssocDerive<NoSerdeImpl>>();
|
assert::<AssocDerive<NoSerdeImpl>>();
|
||||||
@@ -571,6 +603,46 @@ fn test_gen() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert::<AssocDeriveMulti<i32, NoSerdeImpl>>();
|
assert::<AssocDeriveMulti<i32, NoSerdeImpl>>();
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
#[serde(tag = "t", content = "c")]
|
||||||
|
enum EmptyAdjacentlyTagged {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Struct {},
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Tuple(),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_ser::<EmptyAdjacentlyTagged>();
|
||||||
|
|
||||||
|
mod restricted {
|
||||||
|
mod inner {
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Restricted {
|
||||||
|
pub(super) a: usize,
|
||||||
|
pub(in super::inner) b: usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "t", content = "c")]
|
||||||
|
enum AdjacentlyTaggedVoid {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum SkippedVariant<T> {
|
||||||
|
#[serde(skip)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
T(T),
|
||||||
|
Unit,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert::<SkippedVariant<X>>();
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct ImpliciltyBorrowedOption<'a> {
|
||||||
|
option: std::option::Option<&'a str>,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![deny(trivial_numeric_casts)]
|
#![deny(trivial_numeric_casts)]
|
||||||
|
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -18,8 +17,9 @@ extern crate serde_test;
|
|||||||
|
|
||||||
mod bytes;
|
mod bytes;
|
||||||
|
|
||||||
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens,
|
use self::serde_test::{
|
||||||
Token};
|
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token,
|
||||||
|
};
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@@ -226,12 +226,10 @@ fn test_de_named_map() {
|
|||||||
fn test_ser_enum_unit() {
|
fn test_ser_enum_unit() {
|
||||||
assert_ser_tokens(
|
assert_ser_tokens(
|
||||||
&SerEnum::Unit::<u32, u32, u32>,
|
&SerEnum::Unit::<u32, u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "SerEnum",
|
||||||
name: "SerEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,12 +294,10 @@ fn test_ser_enum_map() {
|
|||||||
fn test_de_enum_unit() {
|
fn test_de_enum_unit() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&DeEnum::Unit::<u32, u32, u32>,
|
&DeEnum::Unit::<u32, u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "DeEnum",
|
||||||
name: "DeEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,6 +442,51 @@ fn test_generic_newtype_struct() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_untagged_newtype_struct() {
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum E {
|
||||||
|
Newtype(GenericNewTypeStruct<u32>),
|
||||||
|
Null,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&E::Newtype(GenericNewTypeStruct(5u32)),
|
||||||
|
&[
|
||||||
|
Token::NewtypeStruct {
|
||||||
|
name: "GenericNewTypeStruct",
|
||||||
|
},
|
||||||
|
Token::U32(5),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_adjacently_tagged_newtype_struct() {
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "t", content = "c")]
|
||||||
|
enum E {
|
||||||
|
Newtype(GenericNewTypeStruct<u32>),
|
||||||
|
Null,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(
|
||||||
|
&E::Newtype(GenericNewTypeStruct(5u32)),
|
||||||
|
&[
|
||||||
|
Token::Struct { name: "E", len: 2 },
|
||||||
|
Token::Str("c"),
|
||||||
|
Token::NewtypeStruct {
|
||||||
|
name: "GenericNewTypeStruct",
|
||||||
|
},
|
||||||
|
Token::U32(5),
|
||||||
|
Token::Str("t"),
|
||||||
|
Token::Str("Newtype"),
|
||||||
|
Token::StructEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_generic_tuple_struct() {
|
fn test_generic_tuple_struct() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -466,12 +507,10 @@ fn test_generic_tuple_struct() {
|
|||||||
fn test_generic_enum_unit() {
|
fn test_generic_enum_unit() {
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&GenericEnum::Unit::<u32, u32>,
|
&GenericEnum::Unit::<u32, u32>,
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "GenericEnum",
|
||||||
name: "GenericEnum",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -798,7 +837,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -813,7 +854,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -828,7 +871,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -843,7 +888,9 @@ fn test_internally_tagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&InternallyTagged::String { string: "\0".to_owned() },
|
&InternallyTagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "String",
|
name: "String",
|
||||||
@@ -1354,12 +1401,10 @@ fn test_enum_in_untagged_enum() {
|
|||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&Outer::Inner(Inner::Unit),
|
&Outer::Inner(Inner::Unit),
|
||||||
&[
|
&[Token::UnitVariant {
|
||||||
Token::UnitVariant {
|
name: "Inner",
|
||||||
name: "Inner",
|
variant: "Unit",
|
||||||
variant: "Unit",
|
}],
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
@@ -1417,7 +1462,9 @@ fn test_untagged_bytes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1430,7 +1477,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1443,7 +1492,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
@@ -1456,7 +1507,9 @@ fn test_untagged_bytes() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
&Untagged::String { string: "\0".to_owned() },
|
&Untagged::String {
|
||||||
|
string: "\0".to_owned(),
|
||||||
|
},
|
||||||
&[
|
&[
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Untagged",
|
name: "Untagged",
|
||||||
|
|||||||
@@ -121,10 +121,7 @@ struct UnitDef;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::PrimitivePriv")]
|
#[serde(remote = "remote::PrimitivePriv")]
|
||||||
struct PrimitivePrivDef(
|
struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8);
|
||||||
#[serde(getter = "remote::PrimitivePriv::get")]
|
|
||||||
u8,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::PrimitivePub")]
|
#[serde(remote = "remote::PrimitivePub")]
|
||||||
@@ -132,34 +129,22 @@ struct PrimitivePubDef(u8);
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::NewtypePriv")]
|
#[serde(remote = "remote::NewtypePriv")]
|
||||||
struct NewtypePrivDef(
|
struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit);
|
||||||
#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::NewtypePub")]
|
#[serde(remote = "remote::NewtypePub")]
|
||||||
struct NewtypePubDef(
|
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
|
||||||
#[serde(with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::TuplePriv")]
|
#[serde(remote = "remote::TuplePriv")]
|
||||||
struct TuplePrivDef(
|
struct TuplePrivDef(
|
||||||
#[serde(getter = "remote::TuplePriv::first")]
|
#[serde(getter = "remote::TuplePriv::first")] u8,
|
||||||
u8,
|
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] remote::Unit,
|
||||||
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::TuplePub")]
|
#[serde(remote = "remote::TuplePub")]
|
||||||
struct TuplePubDef(
|
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
|
||||||
u8,
|
|
||||||
#[serde(with = "UnitDef")]
|
|
||||||
remote::Unit,
|
|
||||||
);
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPriv")]
|
#[serde(remote = "remote::StructPriv")]
|
||||||
@@ -175,10 +160,8 @@ struct StructPrivDef {
|
|||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(remote = "remote::StructPub")]
|
#[serde(remote = "remote::StructPub")]
|
||||||
struct StructPubDef {
|
struct StructPubDef {
|
||||||
#[allow(dead_code)]
|
|
||||||
a: u8,
|
a: u8,
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
#[serde(with = "UnitDef")]
|
#[serde(with = "UnitDef")]
|
||||||
b: remote::Unit,
|
b: remote::Unit,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,14 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||||
use std::net;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::rc::Rc;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::net;
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::rc::{Rc, Weak as RcWeak};
|
||||||
|
use std::sync::{Arc, Weak as ArcWeak};
|
||||||
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::str;
|
use std::str;
|
||||||
@@ -398,11 +399,41 @@ declare_tests! {
|
|||||||
Token::Bool(true),
|
Token::Bool(true),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_rc_weak_some {
|
||||||
|
{
|
||||||
|
let rc = Rc::new(true);
|
||||||
|
mem::forget(rc.clone());
|
||||||
|
Rc::downgrade(&rc)
|
||||||
|
} => &[
|
||||||
|
Token::Some,
|
||||||
|
Token::Bool(true),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_rc_weak_none {
|
||||||
|
RcWeak::<bool>::new() => &[
|
||||||
|
Token::None,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_arc {
|
test_arc {
|
||||||
Arc::new(true) => &[
|
Arc::new(true) => &[
|
||||||
Token::Bool(true),
|
Token::Bool(true),
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_arc_weak_some {
|
||||||
|
{
|
||||||
|
let arc = Arc::new(true);
|
||||||
|
mem::forget(arc.clone());
|
||||||
|
Arc::downgrade(&arc)
|
||||||
|
} => &[
|
||||||
|
Token::Some,
|
||||||
|
Token::Bool(true),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
test_arc_weak_none {
|
||||||
|
ArcWeak::<bool>::new() => &[
|
||||||
|
Token::None,
|
||||||
|
],
|
||||||
|
}
|
||||||
test_wrapping {
|
test_wrapping {
|
||||||
Wrapping(1usize) => &[
|
Wrapping(1usize) => &[
|
||||||
Token::U64(1),
|
Token::U64(1),
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
use serde::Deserialize;
|
|
||||||
use serde::de::{value, IntoDeserializer};
|
use serde::de::{value, IntoDeserializer};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_u32_to_enum() {
|
fn test_u32_to_enum() {
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ else
|
|||||||
channel build
|
channel build
|
||||||
cd "$DIR/test_suite"
|
cd "$DIR/test_suite"
|
||||||
channel test --features unstable
|
channel test --features unstable
|
||||||
channel build --tests --features proc-macro2/nightly
|
# Broken while syn and quote update to the new proc-macro API
|
||||||
|
#channel build --tests --features proc-macro2/nightly
|
||||||
if [ -z "${APPVEYOR}" ]; then
|
if [ -z "${APPVEYOR}" ]; then
|
||||||
cd "$DIR/test_suite/no_std"
|
cd "$DIR/test_suite/no_std"
|
||||||
channel build
|
channel build
|
||||||
@@ -87,4 +88,10 @@ else
|
|||||||
channel build --no-default-features
|
channel build --no-default-features
|
||||||
cd "$DIR/serde_test"
|
cd "$DIR/serde_test"
|
||||||
channel build
|
channel build
|
||||||
|
|
||||||
|
CHANNEL=1.15.0
|
||||||
|
cd "$DIR"
|
||||||
|
cargo clean
|
||||||
|
cd "$DIR/serde_derive"
|
||||||
|
channel build
|
||||||
fi
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user