mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-27 11:07:56 +00:00
Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05a5b7e3c6 | |||
| 3bff326fb3 | |||
| aaadd93878 | |||
| 9c864f0b02 | |||
| 070cce0d9c | |||
| b58e8bac12 | |||
| ada50b077e | |||
| 5e313a7330 | |||
| 2a36d11238 | |||
| b6685cf9dd | |||
| fc273c6763 | |||
| bd7b0e257e | |||
| 73931692b2 | |||
| 4d93e9f44c | |||
| da55ed7e8d | |||
| e3617e1f28 | |||
| 431636af0d | |||
| 891ced598a | |||
| 57dc0ee769 | |||
| 5e102c4da1 | |||
| 5c33931422 | |||
| 4aa54222f4 | |||
| ef4f860384 | |||
| 9bd52ec5c1 | |||
| 5cdd82d41e | |||
| 110bf10481 | |||
| 43035f6f37 | |||
| 83b1a3d5dc | |||
| 878110a4bc | |||
| 59ec8b7db2 | |||
| cae1b43829 | |||
| 99fde4ee3e | |||
| afe3872810 | |||
| 3a3e6bf103 | |||
| 935f0bd70f | |||
| 5c18bfeda6 | |||
| 957ef206d1 | |||
| 0c367838cc | |||
| 2023cf345f | |||
| 033d05f70b | |||
| fe4e3fd3b0 | |||
| 8a8a8a70ee | |||
| 339dca828d | |||
| 0d7349fa4e | |||
| 830528d5b1 | |||
| ab90fbc7c9 | |||
| 3eec111e8f | |||
| 9388433642 | |||
| ba12070665 | |||
| a57a324d72 | |||
| 92e91b3557 | |||
| 4dcf791706 | |||
| e77900fb94 | |||
| 1b14cadf20 | |||
| 4f59cd217a | |||
| 27c8b2d66a | |||
| 89976c2712 | |||
| c91737fef1 | |||
| a100719bc6 | |||
| 9a0e149225 | |||
| 9350927903 | |||
| 677c13a4ec | |||
| ee8e1ee7ff | |||
| f969080b9f | |||
| c2b16bfbb0 | |||
| e7df53701c | |||
| 02c34e490b | |||
| 427c839b3d | |||
| f709fc05b0 | |||
| 089aae1292 | |||
| 855acaf112 | |||
| 7ca7720262 | |||
| 78fea3aa4a | |||
| 1efb8b6a53 | |||
| bc1960b106 | |||
| 967023b755 | |||
| bb51e68f16 | |||
| 4e5e55bf1c | |||
| 4513a9e6a7 | |||
| 4f922e4e5b | |||
| 993966600e | |||
| 5b96cf1bde | |||
| f3d50e5209 | |||
| ab21d4d017 | |||
| f7c5d93e6a | |||
| 52a7d40e6e | |||
| 348bc6b257 |
+24
-19
@@ -77,7 +77,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rust: [1.19.0, 1.20.0, 1.21.0, 1.25.0, 1.26.0, 1.34.0]
|
rust: [1.31.0, 1.34.0]
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -88,24 +88,6 @@ jobs:
|
|||||||
- run: cd serde && cargo build --no-default-features
|
- run: cd serde && cargo build --no-default-features
|
||||||
- run: cd serde && cargo build
|
- run: cd serde && cargo build
|
||||||
|
|
||||||
more:
|
|
||||||
name: Rust ${{matrix.rust}}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
rust: [1.27.0, 1.28.0]
|
|
||||||
timeout-minutes: 45
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: dtolnay/rust-toolchain@master
|
|
||||||
with:
|
|
||||||
toolchain: ${{matrix.rust}}
|
|
||||||
# Work around failing to parse manifest because editions are unstable.
|
|
||||||
- run: sed -i /test_suite/d Cargo.toml
|
|
||||||
- run: cd serde && cargo build --no-default-features
|
|
||||||
- run: cd serde && cargo build
|
|
||||||
|
|
||||||
derive:
|
derive:
|
||||||
name: Rust 1.56.0
|
name: Rust 1.56.0
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -127,6 +109,29 @@ jobs:
|
|||||||
- uses: dtolnay/rust-toolchain@1.36.0
|
- uses: dtolnay/rust-toolchain@1.36.0
|
||||||
- run: cd serde && cargo build --no-default-features --features alloc
|
- run: cd serde && cargo build --no-default-features --features alloc
|
||||||
|
|
||||||
|
precompiled:
|
||||||
|
name: Precompiled
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
|
with:
|
||||||
|
components: rust-src
|
||||||
|
targets: x86_64-unknown-linux-musl
|
||||||
|
- run: precompiled/build.sh
|
||||||
|
- name: replace serde_derive dependency with precompiled
|
||||||
|
run: |
|
||||||
|
# FIXME: consider using `cargo rm serde_derive` but it's currently broken
|
||||||
|
# https://github.com/rust-lang/cargo/issues/12419
|
||||||
|
sed -i '/serde_derive =/d' serde/Cargo.toml
|
||||||
|
sed -i '/derive = \["serde_derive"\]/d' serde/Cargo.toml
|
||||||
|
sed -i '/"serde_derive"/d' Cargo.toml
|
||||||
|
sed -i '/\[workspace\]/d' precompiled/serde_derive/Cargo.toml
|
||||||
|
cargo add --dev serde_derive --path precompiled/serde_derive --manifest-path test_suite/Cargo.toml
|
||||||
|
git diff
|
||||||
|
- run: cd test_suite && cargo test --features unstable -- --skip ui --exact
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
name: macOS
|
name: macOS
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.19+]][Rust 1.19] [![serde_derive: rustc 1.56+]][Rust 1.56]
|
# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.31+]][Rust 1.31] [![serde_derive: rustc 1.56+]][Rust 1.56]
|
||||||
|
|
||||||
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
|
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
|
||||||
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
|
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
|
||||||
[Latest Version]: https://img.shields.io/crates/v/serde.svg
|
[Latest Version]: https://img.shields.io/crates/v/serde.svg
|
||||||
[crates.io]: https://crates.io/crates/serde
|
[crates.io]: https://crates.io/crates/serde
|
||||||
[serde: rustc 1.19+]: https://img.shields.io/badge/serde-rustc_1.19+-lightgray.svg
|
[serde: rustc 1.31+]: https://img.shields.io/badge/serde-rustc_1.31+-lightgray.svg
|
||||||
[serde_derive: rustc 1.56+]: https://img.shields.io/badge/serde_derive-rustc_1.56+-lightgray.svg
|
[serde_derive: rustc 1.56+]: https://img.shields.io/badge/serde_derive-rustc_1.56+-lightgray.svg
|
||||||
[Rust 1.19]: https://blog.rust-lang.org/2017/07/20/Rust-1.19.html
|
[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
|
||||||
[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
|
[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
|
||||||
|
|
||||||
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
|
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.178"
|
version = "1.0.183"
|
||||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
@@ -14,4 +14,4 @@ path = "main.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = { version = "1", default-features = false }
|
quote = { version = "1", default-features = false }
|
||||||
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "full", "parsing", "printing"] }
|
syn = { version = "2.0.28", default-features = false, features = ["clone-impls", "derive", "full", "parsing", "printing"] }
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.178"
|
version = "1.0.183"
|
||||||
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||||
categories = ["no-std", "no-std::no-alloc"]
|
categories = ["no-std", "no-std::no-alloc"]
|
||||||
description = "Implementation of #[derive(Serialize, Deserialize)]"
|
description = "Implementation of #[derive(Serialize, Deserialize)]"
|
||||||
@@ -24,7 +24,7 @@ proc-macro = true
|
|||||||
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
|
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
syn = "2.0.25"
|
syn = "2.0.28"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1", path = "../../serde" }
|
serde = { version = "1", path = "../../serde" }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [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.178")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.183")]
|
||||||
|
|
||||||
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
|
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
|
||||||
include!("lib_from_source.rs");
|
include!("lib_from_source.rs");
|
||||||
|
|||||||
+4
-3
@@ -1,20 +1,21 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.178" # remember to update html_root_url and serde_derive dependency
|
version = "1.0.183" # remember to update html_root_url and serde_derive dependency
|
||||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
categories = ["encoding", "no-std", "no-std::no-alloc"]
|
categories = ["encoding", "no-std", "no-std::no-alloc"]
|
||||||
description = "A generic serialization/deserialization framework"
|
description = "A generic serialization/deserialization framework"
|
||||||
documentation = "https://docs.rs/serde"
|
documentation = "https://docs.rs/serde"
|
||||||
|
edition = "2018"
|
||||||
homepage = "https://serde.rs"
|
homepage = "https://serde.rs"
|
||||||
keywords = ["serde", "serialization", "no_std"]
|
keywords = ["serde", "serialization", "no_std"]
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
readme = "crates-io.md"
|
readme = "crates-io.md"
|
||||||
repository = "https://github.com/serde-rs/serde"
|
repository = "https://github.com/serde-rs/serde"
|
||||||
rust-version = "1.19"
|
rust-version = "1.31"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_derive = { version = "=1.0.178", optional = true, path = "../serde_derive" }
|
serde_derive = { version = "=1.0.183", optional = true, path = "../serde_derive" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_derive = { version = "1", path = "../serde_derive" }
|
serde_derive = { version = "1", path = "../serde_derive" }
|
||||||
|
|||||||
+7
-62
@@ -16,68 +16,6 @@ fn main() {
|
|||||||
let target = env::var("TARGET").unwrap();
|
let target = env::var("TARGET").unwrap();
|
||||||
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
|
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
|
||||||
|
|
||||||
// std::collections::Bound was stabilized in Rust 1.17
|
|
||||||
// but it was moved to core::ops later in Rust 1.26:
|
|
||||||
// https://doc.rust-lang.org/core/ops/enum.Bound.html
|
|
||||||
if minor < 26 {
|
|
||||||
println!("cargo:rustc-cfg=no_ops_bound");
|
|
||||||
if minor < 17 {
|
|
||||||
println!("cargo:rustc-cfg=no_collections_bound");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// core::cmp::Reverse stabilized in Rust 1.19:
|
|
||||||
// https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html
|
|
||||||
if minor < 19 {
|
|
||||||
println!("cargo:rustc-cfg=no_core_reverse");
|
|
||||||
}
|
|
||||||
|
|
||||||
// CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20:
|
|
||||||
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
|
|
||||||
// https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path
|
|
||||||
if minor < 20 {
|
|
||||||
println!("cargo:rustc-cfg=no_de_boxed_c_str");
|
|
||||||
println!("cargo:rustc-cfg=no_de_boxed_path");
|
|
||||||
}
|
|
||||||
|
|
||||||
// From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21:
|
|
||||||
// https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>>
|
|
||||||
// https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>>
|
|
||||||
if minor < 21 {
|
|
||||||
println!("cargo:rustc-cfg=no_de_rc_dst");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Duration available in core since Rust 1.25:
|
|
||||||
// https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations
|
|
||||||
if minor < 25 {
|
|
||||||
println!("cargo:rustc-cfg=no_core_duration");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 128-bit integers stabilized in Rust 1.26:
|
|
||||||
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
|
|
||||||
//
|
|
||||||
// Disabled on Emscripten targets before Rust 1.40 since
|
|
||||||
// Emscripten did not support 128-bit integers until Rust 1.40
|
|
||||||
// (https://github.com/rust-lang/rust/pull/65251)
|
|
||||||
if minor < 26 || emscripten && minor < 40 {
|
|
||||||
println!("cargo:rustc-cfg=no_integer128");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inclusive ranges methods stabilized in Rust 1.27:
|
|
||||||
// https://github.com/rust-lang/rust/pull/50758
|
|
||||||
// Also Iterator::try_for_each:
|
|
||||||
// https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations
|
|
||||||
if minor < 27 {
|
|
||||||
println!("cargo:rustc-cfg=no_range_inclusive");
|
|
||||||
println!("cargo:rustc-cfg=no_iterator_try_fold");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-zero integers stabilized in Rust 1.28:
|
|
||||||
// https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations
|
|
||||||
if minor < 28 {
|
|
||||||
println!("cargo:rustc-cfg=no_num_nonzero");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
|
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
|
||||||
// stabilized in Rust 1.34:
|
// stabilized in Rust 1.34:
|
||||||
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
|
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
|
||||||
@@ -89,6 +27,13 @@ fn main() {
|
|||||||
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
|
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disabled on Emscripten targets before Rust 1.40 since
|
||||||
|
// Emscripten did not support 128-bit integers until Rust 1.40
|
||||||
|
// (https://github.com/rust-lang/rust/pull/65251)
|
||||||
|
if emscripten && minor < 40 {
|
||||||
|
println!("cargo:rustc-cfg=no_integer128");
|
||||||
|
}
|
||||||
|
|
||||||
// Current minimum supported version of serde_derive crate is Rust 1.56.
|
// Current minimum supported version of serde_derive crate is Rust 1.56.
|
||||||
if minor < 56 {
|
if minor < 56 {
|
||||||
println!("cargo:rustc-cfg=no_serde_derive");
|
println!("cargo:rustc-cfg=no_serde_derive");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use lib::fmt::{self, Write};
|
use crate::lib::fmt::{self, Write};
|
||||||
use lib::str;
|
use crate::lib::str;
|
||||||
|
|
||||||
pub(super) struct Buf<'a> {
|
pub(super) struct Buf<'a> {
|
||||||
bytes: &'a mut [u8],
|
bytes: &'a mut [u8],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{
|
use crate::de::{
|
||||||
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
|
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
while let Some(IgnoredAny) = try!(seq.next_element()) {
|
while let Some(IgnoredAny) = tri!(seq.next_element()) {
|
||||||
// Gobble
|
// Gobble
|
||||||
}
|
}
|
||||||
Ok(IgnoredAny)
|
Ok(IgnoredAny)
|
||||||
@@ -208,7 +208,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
|||||||
where
|
where
|
||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) {
|
while let Some((IgnoredAny, IgnoredAny)) = tri!(map.next_entry()) {
|
||||||
// Gobble
|
// Gobble
|
||||||
}
|
}
|
||||||
Ok(IgnoredAny)
|
Ok(IgnoredAny)
|
||||||
@@ -227,7 +227,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
|||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
try!(data.variant::<IgnoredAny>()).1.newtype_variant()
|
tri!(data.variant::<IgnoredAny>()).1.newtype_variant()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+74
-116
@@ -1,16 +1,14 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{
|
use crate::de::{
|
||||||
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
|
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, Unexpected, VariantAccess,
|
||||||
|
Visitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc", not(no_core_duration)))]
|
use crate::seed::InPlaceSeed;
|
||||||
use de::MapAccess;
|
|
||||||
|
|
||||||
use seed::InPlaceSeed;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use __private::size_hint;
|
use crate::de::size_hint;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -84,7 +82,7 @@ macro_rules! impl_deserialize_num {
|
|||||||
($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
|
($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
|
||||||
impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
|
impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
|
||||||
|
|
||||||
#[cfg(all(not(no_num_nonzero), $($($cfg)*)*))]
|
$(#[cfg($($cfg)*)])*
|
||||||
impl<'de> Deserialize<'de> for num::$nonzero {
|
impl<'de> Deserialize<'de> for num::$nonzero {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
@@ -684,7 +682,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
|
|||||||
let capacity = size_hint::cautious::<u8>(seq.size_hint());
|
let capacity = size_hint::cautious::<u8>(seq.size_hint());
|
||||||
let mut values = Vec::<u8>::with_capacity(capacity);
|
let mut values = Vec::<u8>::with_capacity(capacity);
|
||||||
|
|
||||||
while let Some(value) = try!(seq.next_element()) {
|
while let Some(value) = tri!(seq.next_element()) {
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,13 +745,9 @@ macro_rules! forwarded_impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
|
||||||
any(feature = "std", all(not(no_core_cstr), feature = "alloc")),
|
|
||||||
not(no_de_boxed_c_str)
|
|
||||||
))]
|
|
||||||
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
|
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
|
||||||
|
|
||||||
#[cfg(not(no_core_reverse))]
|
|
||||||
forwarded_impl!((T), Reverse<T>, Reverse);
|
forwarded_impl!((T), Reverse<T>, Reverse);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -901,7 +895,7 @@ macro_rules! seq_impl {
|
|||||||
{
|
{
|
||||||
let mut values = $with_capacity;
|
let mut values = $with_capacity;
|
||||||
|
|
||||||
while let Some(value) = try!($access.next_element()) {
|
while let Some(value) = tri!($access.next_element()) {
|
||||||
$insert(&mut values, value);
|
$insert(&mut values, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -939,7 +933,7 @@ macro_rules! seq_impl {
|
|||||||
$reserve(&mut self.0, size_hint::cautious::<T>($access.size_hint()));
|
$reserve(&mut self.0, size_hint::cautious::<T>($access.size_hint()));
|
||||||
|
|
||||||
// FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
|
// FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
|
||||||
while let Some(value) = try!($access.next_element()) {
|
while let Some(value) = tri!($access.next_element()) {
|
||||||
$insert(&mut self.0, value);
|
$insert(&mut self.0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,7 +1033,7 @@ where
|
|||||||
let capacity = size_hint::cautious::<T>(seq.size_hint());
|
let capacity = size_hint::cautious::<T>(seq.size_hint());
|
||||||
let mut values = Vec::<T>::with_capacity(capacity);
|
let mut values = Vec::<T>::with_capacity(capacity);
|
||||||
|
|
||||||
while let Some(value) = try!(seq.next_element()) {
|
while let Some(value) = tri!(seq.next_element()) {
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1081,7 +1075,7 @@ where
|
|||||||
for i in 0..self.0.len() {
|
for i in 0..self.0.len() {
|
||||||
let next = {
|
let next = {
|
||||||
let next_place = InPlaceSeed(&mut self.0[i]);
|
let next_place = InPlaceSeed(&mut self.0[i]);
|
||||||
try!(seq.next_element_seed(next_place))
|
tri!(seq.next_element_seed(next_place))
|
||||||
};
|
};
|
||||||
if next.is_none() {
|
if next.is_none() {
|
||||||
self.0.truncate(i);
|
self.0.truncate(i);
|
||||||
@@ -1089,7 +1083,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(value) = try!(seq.next_element()) {
|
while let Some(value) = tri!(seq.next_element()) {
|
||||||
self.0.push(value);
|
self.0.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1161,7 +1155,7 @@ macro_rules! array_impls {
|
|||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
Ok([$(
|
Ok([$(
|
||||||
match try!(seq.next_element()) {
|
match tri!(seq.next_element()) {
|
||||||
Some(val) => val,
|
Some(val) => val,
|
||||||
None => return Err(Error::invalid_length($n, &self)),
|
None => return Err(Error::invalid_length($n, &self)),
|
||||||
}
|
}
|
||||||
@@ -1186,7 +1180,7 @@ macro_rules! array_impls {
|
|||||||
{
|
{
|
||||||
let mut fail_idx = None;
|
let mut fail_idx = None;
|
||||||
for (idx, dest) in self.0[..].iter_mut().enumerate() {
|
for (idx, dest) in self.0[..].iter_mut().enumerate() {
|
||||||
if try!(seq.next_element_seed(InPlaceSeed(dest))).is_none() {
|
if tri!(seq.next_element_seed(InPlaceSeed(dest))).is_none() {
|
||||||
fail_idx = Some(idx);
|
fail_idx = Some(idx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1284,7 +1278,7 @@ macro_rules! tuple_impls {
|
|||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
$(
|
$(
|
||||||
let $name = match try!(seq.next_element()) {
|
let $name = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => return Err(Error::invalid_length($n, &self)),
|
None => return Err(Error::invalid_length($n, &self)),
|
||||||
};
|
};
|
||||||
@@ -1318,7 +1312,7 @@ macro_rules! tuple_impls {
|
|||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
$(
|
$(
|
||||||
if try!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
|
if tri!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
|
||||||
return Err(Error::invalid_length($n, &self));
|
return Err(Error::invalid_length($n, &self));
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@@ -1395,7 +1389,7 @@ macro_rules! map_impl {
|
|||||||
{
|
{
|
||||||
let mut values = $with_capacity;
|
let mut values = $with_capacity;
|
||||||
|
|
||||||
while let Some((key, value)) = try!($access.next_entry()) {
|
while let Some((key, value)) = tri!($access.next_entry()) {
|
||||||
values.insert(key, value);
|
values.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1541,7 +1535,7 @@ macro_rules! deserialize_enum {
|
|||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
match try!(data.variant()) {
|
match tri!(data.variant()) {
|
||||||
$(
|
$(
|
||||||
($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
|
($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
|
||||||
)*
|
)*
|
||||||
@@ -1561,7 +1555,7 @@ impl<'de> Deserialize<'de> for net::IpAddr {
|
|||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
deserializer.deserialize_str(FromStrVisitor::new("IP address"))
|
deserializer.deserialize_str(FromStrVisitor::new("IP address"))
|
||||||
} else {
|
} else {
|
||||||
use lib::net::IpAddr;
|
use crate::lib::net::IpAddr;
|
||||||
deserialize_enum! {
|
deserialize_enum! {
|
||||||
IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
|
IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
|
||||||
"`V4` or `V6`",
|
"`V4` or `V6`",
|
||||||
@@ -1604,7 +1598,7 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
|
|||||||
if deserializer.is_human_readable() {
|
if deserializer.is_human_readable() {
|
||||||
deserializer.deserialize_str(FromStrVisitor::new("socket address"))
|
deserializer.deserialize_str(FromStrVisitor::new("socket address"))
|
||||||
} else {
|
} else {
|
||||||
use lib::net::SocketAddr;
|
use crate::lib::net::SocketAddr;
|
||||||
deserialize_enum! {
|
deserialize_enum! {
|
||||||
SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
|
SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
|
||||||
"`V4` or `V6`",
|
"`V4` or `V6`",
|
||||||
@@ -1714,7 +1708,7 @@ impl<'de> Deserialize<'de> for PathBuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(no_de_boxed_path)))]
|
#[cfg(feature = "std")]
|
||||||
forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path);
|
forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1748,7 +1742,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
{
|
{
|
||||||
use std::os::unix::ffi::OsStringExt;
|
use std::os::unix::ffi::OsStringExt;
|
||||||
|
|
||||||
match try!(data.variant()) {
|
match tri!(data.variant()) {
|
||||||
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
|
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
|
||||||
(OsStringKind::Windows, _) => Err(Error::custom(
|
(OsStringKind::Windows, _) => Err(Error::custom(
|
||||||
"cannot deserialize Windows OS string on Unix",
|
"cannot deserialize Windows OS string on Unix",
|
||||||
@@ -1763,7 +1757,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
|
|||||||
{
|
{
|
||||||
use std::os::windows::ffi::OsStringExt;
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
|
||||||
match try!(data.variant()) {
|
match tri!(data.variant()) {
|
||||||
(OsStringKind::Windows, v) => v
|
(OsStringKind::Windows, v) => v
|
||||||
.newtype_variant::<Vec<u16>>()
|
.newtype_variant::<Vec<u16>>()
|
||||||
.map(|vec| OsString::from_wide(&vec)),
|
.map(|vec| OsString::from_wide(&vec)),
|
||||||
@@ -1795,29 +1789,8 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
|
|||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
forwarded_impl!((), Box<str>, String::into_boxed_str);
|
forwarded_impl!((), Box<str>, String::into_boxed_str);
|
||||||
|
|
||||||
#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
|
#[cfg(all(feature = "std", any(unix, windows)))]
|
||||||
forwarded_impl! {
|
forwarded_impl!((), Box<OsStr>, OsString::into_boxed_os_str);
|
||||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
|
||||||
///
|
|
||||||
/// Deserializing a data structure containing `Arc` will not attempt to
|
|
||||||
/// deduplicate `Arc` references to the same data. Every deserialized `Arc`
|
|
||||||
/// will end up with a strong count of 1.
|
|
||||||
///
|
|
||||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
|
||||||
(T), Arc<T>, Arc::new
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
|
|
||||||
forwarded_impl! {
|
|
||||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
|
||||||
///
|
|
||||||
/// Deserializing a data structure containing `Rc` will not attempt to
|
|
||||||
/// deduplicate `Rc` references to the same data. Every deserialized `Rc`
|
|
||||||
/// will end up with a strong count of 1.
|
|
||||||
///
|
|
||||||
/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
|
|
||||||
(T), Rc<T>, Rc::new
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
|
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
|
||||||
@@ -1849,7 +1822,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
try!(Option::<T>::deserialize(deserializer));
|
tri!(Option::<T>::deserialize(deserializer));
|
||||||
Ok(RcWeak::new())
|
Ok(RcWeak::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1867,18 +1840,14 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
try!(Option::<T>::deserialize(deserializer));
|
tri!(Option::<T>::deserialize(deserializer));
|
||||||
Ok(ArcWeak::new())
|
Ok(ArcWeak::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
not(no_de_rc_dst),
|
|
||||||
feature = "rc",
|
|
||||||
any(feature = "std", feature = "alloc")
|
|
||||||
))]
|
|
||||||
macro_rules! box_forwarded_impl {
|
macro_rules! box_forwarded_impl {
|
||||||
(
|
(
|
||||||
$(#[doc = $doc:tt])*
|
$(#[doc = $doc:tt])*
|
||||||
@@ -1899,11 +1868,7 @@ macro_rules! box_forwarded_impl {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
not(no_de_rc_dst),
|
|
||||||
feature = "rc",
|
|
||||||
any(feature = "std", feature = "alloc")
|
|
||||||
))]
|
|
||||||
box_forwarded_impl! {
|
box_forwarded_impl! {
|
||||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||||
///
|
///
|
||||||
@@ -1915,11 +1880,7 @@ box_forwarded_impl! {
|
|||||||
Rc
|
Rc
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
|
||||||
not(no_de_rc_dst),
|
|
||||||
feature = "rc",
|
|
||||||
any(feature = "std", feature = "alloc")
|
|
||||||
))]
|
|
||||||
box_forwarded_impl! {
|
box_forwarded_impl! {
|
||||||
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
/// This impl requires the [`"rc"`] Cargo feature of Serde.
|
||||||
///
|
///
|
||||||
@@ -1963,7 +1924,6 @@ forwarded_impl!((T), RwLock<T>, RwLock::new);
|
|||||||
// secs: u64,
|
// secs: u64,
|
||||||
// nanos: u32,
|
// nanos: u32,
|
||||||
// }
|
// }
|
||||||
#[cfg(any(feature = "std", not(no_core_duration)))]
|
|
||||||
impl<'de> Deserialize<'de> for Duration {
|
impl<'de> Deserialize<'de> for Duration {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
@@ -2011,7 +1971,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
b"secs" => Ok(Field::Secs),
|
b"secs" => Ok(Field::Secs),
|
||||||
b"nanos" => Ok(Field::Nanos),
|
b"nanos" => Ok(Field::Nanos),
|
||||||
_ => {
|
_ => {
|
||||||
let value = ::__private::from_utf8_lossy(value);
|
let value = crate::__private::from_utf8_lossy(value);
|
||||||
Err(Error::unknown_field(&*value, FIELDS))
|
Err(Error::unknown_field(&*value, FIELDS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2046,19 +2006,19 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let secs: u64 = match try!(seq.next_element()) {
|
let secs: u64 = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(0, &self));
|
return Err(Error::invalid_length(0, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let nanos: u32 = match try!(seq.next_element()) {
|
let nanos: u32 = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(1, &self));
|
return Err(Error::invalid_length(1, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
try!(check_overflow(secs, nanos));
|
tri!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2068,19 +2028,19 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
{
|
{
|
||||||
let mut secs: Option<u64> = None;
|
let mut secs: Option<u64> = None;
|
||||||
let mut nanos: Option<u32> = None;
|
let mut nanos: Option<u32> = None;
|
||||||
while let Some(key) = try!(map.next_key()) {
|
while let Some(key) = tri!(map.next_key()) {
|
||||||
match key {
|
match key {
|
||||||
Field::Secs => {
|
Field::Secs => {
|
||||||
if secs.is_some() {
|
if secs.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("secs"));
|
return Err(<A::Error as Error>::duplicate_field("secs"));
|
||||||
}
|
}
|
||||||
secs = Some(try!(map.next_value()));
|
secs = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
Field::Nanos => {
|
Field::Nanos => {
|
||||||
if nanos.is_some() {
|
if nanos.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("nanos"));
|
return Err(<A::Error as Error>::duplicate_field("nanos"));
|
||||||
}
|
}
|
||||||
nanos = Some(try!(map.next_value()));
|
nanos = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2092,7 +2052,7 @@ impl<'de> Deserialize<'de> for Duration {
|
|||||||
Some(nanos) => nanos,
|
Some(nanos) => nanos,
|
||||||
None => return Err(<A::Error as Error>::missing_field("nanos")),
|
None => return Err(<A::Error as Error>::missing_field("nanos")),
|
||||||
};
|
};
|
||||||
try!(check_overflow(secs, nanos));
|
tri!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2184,19 +2144,19 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let secs: u64 = match try!(seq.next_element()) {
|
let secs: u64 = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(0, &self));
|
return Err(Error::invalid_length(0, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let nanos: u32 = match try!(seq.next_element()) {
|
let nanos: u32 = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(1, &self));
|
return Err(Error::invalid_length(1, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
try!(check_overflow(secs, nanos));
|
tri!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2206,7 +2166,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
{
|
{
|
||||||
let mut secs: Option<u64> = None;
|
let mut secs: Option<u64> = None;
|
||||||
let mut nanos: Option<u32> = None;
|
let mut nanos: Option<u32> = None;
|
||||||
while let Some(key) = try!(map.next_key()) {
|
while let Some(key) = tri!(map.next_key()) {
|
||||||
match key {
|
match key {
|
||||||
Field::Secs => {
|
Field::Secs => {
|
||||||
if secs.is_some() {
|
if secs.is_some() {
|
||||||
@@ -2214,7 +2174,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
"secs_since_epoch",
|
"secs_since_epoch",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
secs = Some(try!(map.next_value()));
|
secs = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
Field::Nanos => {
|
Field::Nanos => {
|
||||||
if nanos.is_some() {
|
if nanos.is_some() {
|
||||||
@@ -2222,7 +2182,7 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
"nanos_since_epoch",
|
"nanos_since_epoch",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
nanos = Some(try!(map.next_value()));
|
nanos = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2234,13 +2194,13 @@ impl<'de> Deserialize<'de> for SystemTime {
|
|||||||
Some(nanos) => nanos,
|
Some(nanos) => nanos,
|
||||||
None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
|
None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
|
||||||
};
|
};
|
||||||
try!(check_overflow(secs, nanos));
|
tri!(check_overflow(secs, nanos));
|
||||||
Ok(Duration::new(secs, nanos))
|
Ok(Duration::new(secs, nanos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"];
|
const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"];
|
||||||
let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
|
let duration = tri!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
|
||||||
#[cfg(not(no_systemtime_checked_add))]
|
#[cfg(not(no_systemtime_checked_add))]
|
||||||
let ret = UNIX_EPOCH
|
let ret = UNIX_EPOCH
|
||||||
.checked_add(duration)
|
.checked_add(duration)
|
||||||
@@ -2269,7 +2229,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let (start, end) = try!(deserializer.deserialize_struct(
|
let (start, end) = tri!(deserializer.deserialize_struct(
|
||||||
"Range",
|
"Range",
|
||||||
range::FIELDS,
|
range::FIELDS,
|
||||||
range::RangeVisitor {
|
range::RangeVisitor {
|
||||||
@@ -2281,7 +2241,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(no_range_inclusive))]
|
|
||||||
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
|
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
|
||||||
where
|
where
|
||||||
Idx: Deserialize<'de>,
|
Idx: Deserialize<'de>,
|
||||||
@@ -2290,7 +2249,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let (start, end) = try!(deserializer.deserialize_struct(
|
let (start, end) = tri!(deserializer.deserialize_struct(
|
||||||
"RangeInclusive",
|
"RangeInclusive",
|
||||||
range::FIELDS,
|
range::FIELDS,
|
||||||
range::RangeVisitor {
|
range::RangeVisitor {
|
||||||
@@ -2303,9 +2262,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod range {
|
mod range {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||||
|
|
||||||
pub const FIELDS: &[&str] = &["start", "end"];
|
pub const FIELDS: &[&str] = &["start", "end"];
|
||||||
|
|
||||||
@@ -2351,7 +2310,7 @@ mod range {
|
|||||||
b"start" => Ok(Field::Start),
|
b"start" => Ok(Field::Start),
|
||||||
b"end" => Ok(Field::End),
|
b"end" => Ok(Field::End),
|
||||||
_ => {
|
_ => {
|
||||||
let value = ::__private::from_utf8_lossy(value);
|
let value = crate::__private::from_utf8_lossy(value);
|
||||||
Err(Error::unknown_field(&*value, FIELDS))
|
Err(Error::unknown_field(&*value, FIELDS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2381,13 +2340,13 @@ mod range {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let start: Idx = match try!(seq.next_element()) {
|
let start: Idx = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(0, &self));
|
return Err(Error::invalid_length(0, &self));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let end: Idx = match try!(seq.next_element()) {
|
let end: Idx = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(1, &self));
|
return Err(Error::invalid_length(1, &self));
|
||||||
@@ -2402,19 +2361,19 @@ mod range {
|
|||||||
{
|
{
|
||||||
let mut start: Option<Idx> = None;
|
let mut start: Option<Idx> = None;
|
||||||
let mut end: Option<Idx> = None;
|
let mut end: Option<Idx> = None;
|
||||||
while let Some(key) = try!(map.next_key()) {
|
while let Some(key) = tri!(map.next_key()) {
|
||||||
match key {
|
match key {
|
||||||
Field::Start => {
|
Field::Start => {
|
||||||
if start.is_some() {
|
if start.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("start"));
|
return Err(<A::Error as Error>::duplicate_field("start"));
|
||||||
}
|
}
|
||||||
start = Some(try!(map.next_value()));
|
start = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
Field::End => {
|
Field::End => {
|
||||||
if end.is_some() {
|
if end.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("end"));
|
return Err(<A::Error as Error>::duplicate_field("end"));
|
||||||
}
|
}
|
||||||
end = Some(try!(map.next_value()));
|
end = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2448,7 +2407,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let start = try!(deserializer.deserialize_struct(
|
let start = tri!(deserializer.deserialize_struct(
|
||||||
"RangeFrom",
|
"RangeFrom",
|
||||||
range_from::FIELDS,
|
range_from::FIELDS,
|
||||||
range_from::RangeFromVisitor {
|
range_from::RangeFromVisitor {
|
||||||
@@ -2461,9 +2420,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod range_from {
|
mod range_from {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||||
|
|
||||||
pub const FIELDS: &[&str] = &["end"];
|
pub const FIELDS: &[&str] = &["end"];
|
||||||
|
|
||||||
@@ -2506,7 +2465,7 @@ mod range_from {
|
|||||||
match value {
|
match value {
|
||||||
b"end" => Ok(Field::End),
|
b"end" => Ok(Field::End),
|
||||||
_ => {
|
_ => {
|
||||||
let value = ::__private::from_utf8_lossy(value);
|
let value = crate::__private::from_utf8_lossy(value);
|
||||||
Err(Error::unknown_field(&*value, FIELDS))
|
Err(Error::unknown_field(&*value, FIELDS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2536,7 +2495,7 @@ mod range_from {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let end: Idx = match try!(seq.next_element()) {
|
let end: Idx = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(0, &self));
|
return Err(Error::invalid_length(0, &self));
|
||||||
@@ -2550,13 +2509,13 @@ mod range_from {
|
|||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut end: Option<Idx> = None;
|
let mut end: Option<Idx> = None;
|
||||||
while let Some(key) = try!(map.next_key()) {
|
while let Some(key) = tri!(map.next_key()) {
|
||||||
match key {
|
match key {
|
||||||
Field::End => {
|
Field::End => {
|
||||||
if end.is_some() {
|
if end.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("end"));
|
return Err(<A::Error as Error>::duplicate_field("end"));
|
||||||
}
|
}
|
||||||
end = Some(try!(map.next_value()));
|
end = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2586,7 +2545,7 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let end = try!(deserializer.deserialize_struct(
|
let end = tri!(deserializer.deserialize_struct(
|
||||||
"RangeTo",
|
"RangeTo",
|
||||||
range_to::FIELDS,
|
range_to::FIELDS,
|
||||||
range_to::RangeToVisitor {
|
range_to::RangeToVisitor {
|
||||||
@@ -2599,9 +2558,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod range_to {
|
mod range_to {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
|
||||||
|
|
||||||
pub const FIELDS: &[&str] = &["start"];
|
pub const FIELDS: &[&str] = &["start"];
|
||||||
|
|
||||||
@@ -2644,7 +2603,7 @@ mod range_to {
|
|||||||
match value {
|
match value {
|
||||||
b"start" => Ok(Field::Start),
|
b"start" => Ok(Field::Start),
|
||||||
_ => {
|
_ => {
|
||||||
let value = ::__private::from_utf8_lossy(value);
|
let value = crate::__private::from_utf8_lossy(value);
|
||||||
Err(Error::unknown_field(&*value, FIELDS))
|
Err(Error::unknown_field(&*value, FIELDS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2674,7 +2633,7 @@ mod range_to {
|
|||||||
where
|
where
|
||||||
A: SeqAccess<'de>,
|
A: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let start: Idx = match try!(seq.next_element()) {
|
let start: Idx = match tri!(seq.next_element()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => {
|
None => {
|
||||||
return Err(Error::invalid_length(0, &self));
|
return Err(Error::invalid_length(0, &self));
|
||||||
@@ -2688,13 +2647,13 @@ mod range_to {
|
|||||||
A: MapAccess<'de>,
|
A: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
let mut start: Option<Idx> = None;
|
let mut start: Option<Idx> = None;
|
||||||
while let Some(key) = try!(map.next_key()) {
|
while let Some(key) = tri!(map.next_key()) {
|
||||||
match key {
|
match key {
|
||||||
Field::Start => {
|
Field::Start => {
|
||||||
if start.is_some() {
|
if start.is_some() {
|
||||||
return Err(<A::Error as Error>::duplicate_field("start"));
|
return Err(<A::Error as Error>::duplicate_field("start"));
|
||||||
}
|
}
|
||||||
start = Some(try!(map.next_value()));
|
start = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2709,7 +2668,6 @@ mod range_to {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
|
|
||||||
impl<'de, T> Deserialize<'de> for Bound<T>
|
impl<'de, T> Deserialize<'de> for Bound<T>
|
||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
@@ -2801,7 +2759,7 @@ where
|
|||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
match try!(data.variant()) {
|
match tri!(data.variant()) {
|
||||||
(Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded),
|
(Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded),
|
||||||
(Field::Included, v) => v.newtype_variant().map(Bound::Included),
|
(Field::Included, v) => v.newtype_variant().map(Bound::Included),
|
||||||
(Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
|
(Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
|
||||||
@@ -2910,7 +2868,7 @@ where
|
|||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
match try!(data.variant()) {
|
match tri!(data.variant()) {
|
||||||
(Field::Ok, v) => v.newtype_variant().map(Ok),
|
(Field::Ok, v) => v.newtype_variant().map(Ok),
|
||||||
(Field::Err, v) => v.newtype_variant().map(Err),
|
(Field::Err, v) => v.newtype_variant().map(Err),
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-13
@@ -112,7 +112,7 @@
|
|||||||
//! [derive section of the manual]: https://serde.rs/derive.html
|
//! [derive section of the manual]: https://serde.rs/derive.html
|
||||||
//! [data formats]: https://serde.rs/#data-formats
|
//! [data formats]: https://serde.rs/#data-formats
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -122,19 +122,20 @@ pub mod value;
|
|||||||
mod format;
|
mod format;
|
||||||
mod ignored_any;
|
mod ignored_any;
|
||||||
mod impls;
|
mod impls;
|
||||||
|
pub(crate) mod size_hint;
|
||||||
mod utf8;
|
mod utf8;
|
||||||
|
|
||||||
pub use self::ignored_any::IgnoredAny;
|
pub use self::ignored_any::IgnoredAny;
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "std", feature = "unstable")))]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::std_error::Error as StdError;
|
||||||
#[cfg(all(feature = "unstable", not(feature = "std")))]
|
#[cfg(all(feature = "unstable", not(feature = "std")))]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use core::error::Error as StdError;
|
pub use core::error::Error as StdError;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use std::error::Error as StdError;
|
pub use std::error::Error as StdError;
|
||||||
#[cfg(not(any(feature = "std", feature = "unstable")))]
|
|
||||||
#[doc(no_inline)]
|
|
||||||
pub use std_error::Error as StdError;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -569,7 +570,7 @@ pub trait Deserialize<'de>: Sized {
|
|||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
// Default implementation just delegates to `deserialize` impl.
|
// Default implementation just delegates to `deserialize` impl.
|
||||||
*place = try!(Deserialize::deserialize(deserializer));
|
*place = tri!(Deserialize::deserialize(deserializer));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1229,11 +1230,11 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn __deserialize_content<V>(
|
fn __deserialize_content<V>(
|
||||||
self,
|
self,
|
||||||
_: ::actually_private::T,
|
_: crate::actually_private::T,
|
||||||
visitor: V,
|
visitor: V,
|
||||||
) -> Result<::private::de::Content<'de>, Self::Error>
|
) -> Result<crate::__private::de::Content<'de>, Self::Error>
|
||||||
where
|
where
|
||||||
V: Visitor<'de, Value = ::private::de::Content<'de>>,
|
V: Visitor<'de, Value = crate::__private::de::Content<'de>>,
|
||||||
{
|
{
|
||||||
self.deserialize_any(visitor)
|
self.deserialize_any(visitor)
|
||||||
}
|
}
|
||||||
@@ -1834,9 +1835,9 @@ pub trait MapAccess<'de> {
|
|||||||
K: DeserializeSeed<'de>,
|
K: DeserializeSeed<'de>,
|
||||||
V: DeserializeSeed<'de>,
|
V: DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match try!(self.next_key_seed(kseed)) {
|
match tri!(self.next_key_seed(kseed)) {
|
||||||
Some(key) => {
|
Some(key) => {
|
||||||
let value = try!(self.next_value_seed(vseed));
|
let value = tri!(self.next_value_seed(vseed));
|
||||||
Ok(Some((key, value)))
|
Ok(Some((key, value)))
|
||||||
}
|
}
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
@@ -2284,12 +2285,12 @@ impl Display for OneOf {
|
|||||||
1 => write!(formatter, "`{}`", self.names[0]),
|
1 => write!(formatter, "`{}`", self.names[0]),
|
||||||
2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]),
|
2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]),
|
||||||
_ => {
|
_ => {
|
||||||
try!(write!(formatter, "one of "));
|
tri!(write!(formatter, "one of "));
|
||||||
for (i, alt) in self.names.iter().enumerate() {
|
for (i, alt) in self.names.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
try!(write!(formatter, ", "));
|
tri!(write!(formatter, ", "));
|
||||||
}
|
}
|
||||||
try!(write!(formatter, "`{}`", alt));
|
tri!(write!(formatter, "`{}`", alt));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use de::{Deserialize, DeserializeSeed, Deserializer};
|
use crate::de::{Deserialize, DeserializeSeed, Deserializer};
|
||||||
|
|
||||||
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
pub fn from_bounds<I>(iter: &I) -> Option<usize>
|
pub fn from_bounds<I>(iter: &I) -> Option<usize>
|
||||||
where
|
where
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
const TAG_CONT: u8 = 0b1000_0000;
|
const TAG_CONT: u8 = 0b1000_0000;
|
||||||
const TAG_TWO_B: u8 = 0b1100_0000;
|
const TAG_TWO_B: u8 = 0b1100_0000;
|
||||||
|
|||||||
+17
-16
@@ -21,12 +21,11 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use self::private::{First, Second};
|
use self::private::{First, Second};
|
||||||
use __private::size_hint;
|
use crate::de::{self, size_hint, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
|
||||||
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
|
use crate::ser;
|
||||||
use ser;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -937,8 +936,8 @@ where
|
|||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
let v = try!(visitor.visit_seq(&mut self));
|
let v = tri!(visitor.visit_seq(&mut self));
|
||||||
try!(self.end());
|
tri!(self.end());
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1162,8 +1161,8 @@ where
|
|||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = try!(visitor.visit_map(&mut self));
|
let value = tri!(visitor.visit_map(&mut self));
|
||||||
try!(self.end());
|
tri!(self.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1171,8 +1170,8 @@ where
|
|||||||
where
|
where
|
||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
let value = try!(visitor.visit_seq(&mut self));
|
let value = tri!(visitor.visit_seq(&mut self));
|
||||||
try!(self.end());
|
tri!(self.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1236,8 +1235,8 @@ where
|
|||||||
{
|
{
|
||||||
match self.next_pair() {
|
match self.next_pair() {
|
||||||
Some((key, value)) => {
|
Some((key, value)) => {
|
||||||
let key = try!(kseed.deserialize(key.into_deserializer()));
|
let key = tri!(kseed.deserialize(key.into_deserializer()));
|
||||||
let value = try!(vseed.deserialize(value.into_deserializer()));
|
let value = tri!(vseed.deserialize(value.into_deserializer()));
|
||||||
Ok(Some((key, value)))
|
Ok(Some((key, value)))
|
||||||
}
|
}
|
||||||
None => Ok(None),
|
None => Ok(None),
|
||||||
@@ -1341,7 +1340,7 @@ where
|
|||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData);
|
let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData);
|
||||||
let pair = try!(visitor.visit_seq(&mut pair_visitor));
|
let pair = tri!(visitor.visit_seq(&mut pair_visitor));
|
||||||
if pair_visitor.1.is_none() {
|
if pair_visitor.1.is_none() {
|
||||||
Ok(pair)
|
Ok(pair)
|
||||||
} else {
|
} else {
|
||||||
@@ -1501,7 +1500,7 @@ where
|
|||||||
where
|
where
|
||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match try!(self.map.next_key_seed(seed)) {
|
match tri!(self.map.next_key_seed(seed)) {
|
||||||
Some(key) => Ok((key, private::map_as_enum(self.map))),
|
Some(key) => Ok((key, private::map_as_enum(self.map))),
|
||||||
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
|
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
|
||||||
}
|
}
|
||||||
@@ -1546,9 +1545,11 @@ where
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor};
|
use crate::de::{
|
||||||
|
self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct UnitOnly<E> {
|
pub struct UnitOnly<E> {
|
||||||
marker: PhantomData<E>,
|
marker: PhantomData<E>,
|
||||||
|
|||||||
+50
-72
@@ -93,7 +93,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// 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.178")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.183")]
|
||||||
// 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
|
||||||
@@ -102,55 +102,51 @@
|
|||||||
// https://github.com/serde-rs/serde/issues/812
|
// https://github.com/serde-rs/serde/issues/812
|
||||||
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
|
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
|
||||||
#![allow(unknown_lints, bare_trait_objects, deprecated)]
|
#![allow(unknown_lints, bare_trait_objects, deprecated)]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
|
||||||
// Ignored clippy and clippy_pedantic lints
|
// Ignored clippy and clippy_pedantic lints
|
||||||
#![cfg_attr(
|
#![allow(
|
||||||
feature = "cargo-clippy",
|
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||||
allow(
|
clippy::unnested_or_patterns,
|
||||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
|
||||||
unnested_or_patterns,
|
clippy::semicolon_if_nothing_returned,
|
||||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
|
// not available in our oldest supported compiler
|
||||||
semicolon_if_nothing_returned,
|
clippy::empty_enum,
|
||||||
// not available in our oldest supported compiler
|
clippy::type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
|
||||||
empty_enum,
|
// integer and float ser/de requires these sorts of casts
|
||||||
type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
|
clippy::cast_possible_truncation,
|
||||||
// integer and float ser/de requires these sorts of casts
|
clippy::cast_possible_wrap,
|
||||||
cast_possible_truncation,
|
clippy::cast_sign_loss,
|
||||||
cast_possible_wrap,
|
// things are often more readable this way
|
||||||
cast_sign_loss,
|
clippy::cast_lossless,
|
||||||
// things are often more readable this way
|
clippy::module_name_repetitions,
|
||||||
cast_lossless,
|
clippy::option_if_let_else,
|
||||||
module_name_repetitions,
|
clippy::single_match_else,
|
||||||
option_if_let_else,
|
clippy::type_complexity,
|
||||||
single_match_else,
|
clippy::use_self,
|
||||||
type_complexity,
|
clippy::zero_prefixed_literal,
|
||||||
use_self,
|
// correctly used
|
||||||
zero_prefixed_literal,
|
clippy::derive_partial_eq_without_eq,
|
||||||
// correctly used
|
clippy::enum_glob_use,
|
||||||
derive_partial_eq_without_eq,
|
clippy::explicit_auto_deref,
|
||||||
enum_glob_use,
|
clippy::let_underscore_untyped,
|
||||||
explicit_auto_deref,
|
clippy::map_err_ignore,
|
||||||
let_underscore_untyped,
|
clippy::new_without_default,
|
||||||
map_err_ignore,
|
clippy::result_unit_err,
|
||||||
new_without_default,
|
clippy::wildcard_imports,
|
||||||
result_unit_err,
|
// not practical
|
||||||
wildcard_imports,
|
clippy::needless_pass_by_value,
|
||||||
// not practical
|
clippy::similar_names,
|
||||||
needless_pass_by_value,
|
clippy::too_many_lines,
|
||||||
similar_names,
|
// preference
|
||||||
too_many_lines,
|
clippy::doc_markdown,
|
||||||
// preference
|
clippy::unseparated_literal_suffix,
|
||||||
doc_markdown,
|
// false positive
|
||||||
unseparated_literal_suffix,
|
clippy::needless_doctest_main,
|
||||||
// false positive
|
// noisy
|
||||||
needless_doctest_main,
|
clippy::missing_errors_doc,
|
||||||
// noisy
|
clippy::must_use_candidate,
|
||||||
missing_errors_doc,
|
|
||||||
must_use_candidate,
|
|
||||||
)
|
|
||||||
)]
|
)]
|
||||||
// Restrictions
|
// Restrictions
|
||||||
#![cfg_attr(feature = "cargo-clippy", deny(question_mark_used))]
|
#![deny(clippy::question_mark_used)]
|
||||||
// Rustc lints.
|
// Rustc lints.
|
||||||
#![deny(missing_docs, unused_imports)]
|
#![deny(missing_docs, unused_imports)]
|
||||||
|
|
||||||
@@ -177,14 +173,16 @@ mod lib {
|
|||||||
|
|
||||||
pub use self::core::cell::{Cell, RefCell};
|
pub use self::core::cell::{Cell, RefCell};
|
||||||
pub use self::core::clone::{self, Clone};
|
pub use self::core::clone::{self, Clone};
|
||||||
|
pub use self::core::cmp::Reverse;
|
||||||
pub use self::core::convert::{self, From, Into};
|
pub use self::core::convert::{self, From, Into};
|
||||||
pub use self::core::default::{self, Default};
|
pub use self::core::default::{self, Default};
|
||||||
pub use self::core::fmt::{self, Debug, Display};
|
pub use self::core::fmt::{self, Debug, Display};
|
||||||
pub use self::core::marker::{self, PhantomData};
|
pub use self::core::marker::{self, PhantomData};
|
||||||
pub use self::core::num::Wrapping;
|
pub use self::core::num::Wrapping;
|
||||||
pub use self::core::ops::{Range, RangeFrom, RangeTo};
|
pub use self::core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo};
|
||||||
pub use self::core::option::{self, Option};
|
pub use self::core::option::{self, Option};
|
||||||
pub use self::core::result::{self, Result};
|
pub use self::core::result::{self, Result};
|
||||||
|
pub use self::core::time::Duration;
|
||||||
|
|
||||||
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
#[cfg(all(feature = "alloc", not(feature = "std")))]
|
||||||
pub use alloc::borrow::{Cow, ToOwned};
|
pub use alloc::borrow::{Cow, ToOwned};
|
||||||
@@ -222,7 +220,7 @@ mod lib {
|
|||||||
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
|
||||||
|
|
||||||
#[cfg(all(not(no_core_cstr), not(feature = "std")))]
|
#[cfg(all(not(no_core_cstr), not(feature = "std")))]
|
||||||
pub use core::ffi::CStr;
|
pub use self::core::ffi::CStr;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::ffi::CStr;
|
pub use std::ffi::CStr;
|
||||||
|
|
||||||
@@ -249,18 +247,6 @@ mod lib {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub use std::time::{SystemTime, UNIX_EPOCH};
|
pub use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))]
|
|
||||||
pub use std::collections::Bound;
|
|
||||||
|
|
||||||
#[cfg(not(no_core_reverse))]
|
|
||||||
pub use self::core::cmp::Reverse;
|
|
||||||
|
|
||||||
#[cfg(not(no_ops_bound))]
|
|
||||||
pub use self::core::ops::Bound;
|
|
||||||
|
|
||||||
#[cfg(not(no_range_inclusive))]
|
|
||||||
pub use self::core::ops::RangeInclusive;
|
|
||||||
|
|
||||||
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
|
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
|
||||||
pub use std::sync::atomic::{
|
pub use std::sync::atomic::{
|
||||||
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
|
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
|
||||||
@@ -281,16 +267,13 @@ mod lib {
|
|||||||
pub use std::sync::atomic::{AtomicI64, AtomicU64};
|
pub use std::sync::atomic::{AtomicI64, AtomicU64};
|
||||||
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
|
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
|
||||||
pub use std::sync::atomic::{AtomicIsize, AtomicUsize};
|
pub use std::sync::atomic::{AtomicIsize, AtomicUsize};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", not(no_core_duration)))]
|
|
||||||
pub use self::core::time::Duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// None of this crate's error handling needs the `From::from` error conversion
|
// None of this crate's error handling needs the `From::from` error conversion
|
||||||
// performed implicitly by the `?` operator or the standard library's `try!`
|
// performed implicitly by the `?` operator or the standard library's `try!`
|
||||||
// macro. This simplified macro gives a 5.5% improvement in compile time
|
// macro. This simplified macro gives a 5.5% improvement in compile time
|
||||||
// compared to standard `try!`, and 9% improvement compared to `?`.
|
// compared to standard `try!`, and 9% improvement compared to `?`.
|
||||||
macro_rules! try {
|
macro_rules! tri {
|
||||||
($expr:expr) => {
|
($expr:expr) => {
|
||||||
match $expr {
|
match $expr {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
@@ -311,20 +294,15 @@ pub mod de;
|
|||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use de::{Deserialize, Deserializer};
|
pub use crate::de::{Deserialize, Deserializer};
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use ser::{Serialize, Serializer};
|
pub use crate::ser::{Serialize, Serializer};
|
||||||
|
|
||||||
// Used by generated code and doc tests. Not public API.
|
// Used by generated code and doc tests. Not public API.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[path = "private/mod.rs"]
|
#[path = "private/mod.rs"]
|
||||||
pub mod __private;
|
pub mod __private;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use self::__private as export;
|
|
||||||
#[allow(unused_imports)]
|
|
||||||
use self::__private as private;
|
|
||||||
|
|
||||||
#[path = "de/seed.rs"]
|
#[path = "de/seed.rs"]
|
||||||
mod seed;
|
mod seed;
|
||||||
|
|
||||||
|
|||||||
+101
-185
@@ -1,10 +1,13 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
|
use crate::de::value::{BorrowedBytesDeserializer, BytesDeserializer};
|
||||||
use de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor};
|
use crate::de::{
|
||||||
|
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, VariantAccess,
|
||||||
|
Visitor,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use de::{DeserializeSeed, MapAccess, Unexpected};
|
use crate::de::{MapAccess, Unexpected};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub use self::content::{
|
pub use self::content::{
|
||||||
@@ -13,7 +16,7 @@ pub use self::content::{
|
|||||||
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
|
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use seed::InPlaceSeed;
|
pub use crate::seed::InPlaceSeed;
|
||||||
|
|
||||||
/// 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.
|
||||||
@@ -203,13 +206,13 @@ mod content {
|
|||||||
// This issue is tracking making some of this stuff public:
|
// This issue is tracking making some of this stuff public:
|
||||||
// https://github.com/serde-rs/serde/issues/741
|
// https://github.com/serde-rs/serde/issues/741
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use __private::size_hint;
|
use crate::actually_private;
|
||||||
use actually_private;
|
use crate::de::value::{MapDeserializer, SeqDeserializer};
|
||||||
use de::{
|
use crate::de::{
|
||||||
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
|
self, size_hint, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected,
|
||||||
MapAccess, SeqAccess, Unexpected, Visitor,
|
IgnoredAny, 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
|
||||||
@@ -299,6 +302,17 @@ mod content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'de, E> de::IntoDeserializer<'de, E> for Content<'de>
|
||||||
|
where
|
||||||
|
E: de::Error,
|
||||||
|
{
|
||||||
|
type Deserializer = ContentDeserializer<'de, E>;
|
||||||
|
|
||||||
|
fn into_deserializer(self) -> Self::Deserializer {
|
||||||
|
ContentDeserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ContentVisitor<'de> {
|
struct ContentVisitor<'de> {
|
||||||
value: PhantomData<Content<'de>>,
|
value: PhantomData<Content<'de>>,
|
||||||
}
|
}
|
||||||
@@ -476,7 +490,7 @@ mod content {
|
|||||||
{
|
{
|
||||||
let mut vec =
|
let mut vec =
|
||||||
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
|
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
|
||||||
while let Some(e) = try!(visitor.next_element()) {
|
while let Some(e) = tri!(visitor.next_element()) {
|
||||||
vec.push(e);
|
vec.push(e);
|
||||||
}
|
}
|
||||||
Ok(Content::Seq(vec))
|
Ok(Content::Seq(vec))
|
||||||
@@ -490,7 +504,7 @@ mod content {
|
|||||||
Vec::<(Content, Content)>::with_capacity(
|
Vec::<(Content, Content)>::with_capacity(
|
||||||
size_hint::cautious::<(Content, Content)>(visitor.size_hint()),
|
size_hint::cautious::<(Content, Content)>(visitor.size_hint()),
|
||||||
);
|
);
|
||||||
while let Some(kv) = try!(visitor.next_entry()) {
|
while let Some(kv) = tri!(visitor.next_entry()) {
|
||||||
vec.push(kv);
|
vec.push(kv);
|
||||||
}
|
}
|
||||||
Ok(Content::Map(vec))
|
Ok(Content::Map(vec))
|
||||||
@@ -833,14 +847,14 @@ mod content {
|
|||||||
where
|
where
|
||||||
S: SeqAccess<'de>,
|
S: SeqAccess<'de>,
|
||||||
{
|
{
|
||||||
let tag = match try!(seq.next_element()) {
|
let tag = match tri!(seq.next_element()) {
|
||||||
Some(tag) => tag,
|
Some(tag) => tag,
|
||||||
None => {
|
None => {
|
||||||
return Err(de::Error::missing_field(self.tag_name));
|
return Err(de::Error::missing_field(self.tag_name));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let rest = de::value::SeqAccessDeserializer::new(seq);
|
let rest = de::value::SeqAccessDeserializer::new(seq);
|
||||||
Ok((tag, try!(Content::deserialize(rest))))
|
Ok((tag, tri!(Content::deserialize(rest))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
|
||||||
@@ -852,16 +866,16 @@ mod content {
|
|||||||
Content,
|
Content,
|
||||||
Content,
|
Content,
|
||||||
)>(map.size_hint()));
|
)>(map.size_hint()));
|
||||||
while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
|
while let Some(k) = tri!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
|
||||||
match k {
|
match k {
|
||||||
TagOrContent::Tag => {
|
TagOrContent::Tag => {
|
||||||
if tag.is_some() {
|
if tag.is_some() {
|
||||||
return Err(de::Error::duplicate_field(self.tag_name));
|
return Err(de::Error::duplicate_field(self.tag_name));
|
||||||
}
|
}
|
||||||
tag = Some(try!(map.next_value()));
|
tag = Some(tri!(map.next_value()));
|
||||||
}
|
}
|
||||||
TagOrContent::Content(k) => {
|
TagOrContent::Content(k) => {
|
||||||
let v = try!(map.next_value());
|
let v = tri!(map.next_value());
|
||||||
vec.push((k, v));
|
vec.push((k, v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1074,9 +1088,9 @@ mod content {
|
|||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
let seq = content.into_iter().map(ContentDeserializer::new);
|
let seq = content.into_iter().map(ContentDeserializer::new);
|
||||||
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
|
let mut seq_visitor = SeqDeserializer::new(seq);
|
||||||
let value = try!(visitor.visit_seq(&mut seq_visitor));
|
let value = tri!(visitor.visit_seq(&mut seq_visitor));
|
||||||
try!(seq_visitor.end());
|
tri!(seq_visitor.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1091,9 +1105,9 @@ mod content {
|
|||||||
let map = content
|
let map = content
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
|
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
|
||||||
let mut map_visitor = de::value::MapDeserializer::new(map);
|
let mut map_visitor = MapDeserializer::new(map);
|
||||||
let value = try!(visitor.visit_map(&mut map_visitor));
|
let value = tri!(visitor.visit_map(&mut map_visitor));
|
||||||
try!(map_visitor.end());
|
tri!(map_visitor.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1569,7 +1583,7 @@ mod content {
|
|||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(Content::Seq(v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
other.unexpected(),
|
other.unexpected(),
|
||||||
@@ -1592,10 +1606,10 @@ mod content {
|
|||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(Content::Map(v)) => {
|
Some(Content::Map(v)) => {
|
||||||
de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(MapDeserializer::new(v.into_iter()), visitor)
|
||||||
}
|
}
|
||||||
Some(Content::Seq(v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqDeserializer::new(v.into_iter()), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
other.unexpected(),
|
other.unexpected(),
|
||||||
@@ -1609,156 +1623,6 @@ mod content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeqDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
iter: <Vec<Content<'de>> as IntoIterator>::IntoIter,
|
|
||||||
err: PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> SeqDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
fn new(vec: Vec<Content<'de>>) -> Self {
|
|
||||||
SeqDeserializer {
|
|
||||||
iter: vec.into_iter(),
|
|
||||||
err: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
let len = self.iter.len();
|
|
||||||
if len == 0 {
|
|
||||||
visitor.visit_unit()
|
|
||||||
} else {
|
|
||||||
let ret = try!(visitor.visit_seq(&mut self));
|
|
||||||
let remaining = self.iter.len();
|
|
||||||
if remaining == 0 {
|
|
||||||
Ok(ret)
|
|
||||||
} else {
|
|
||||||
Err(de::Error::invalid_length(len, &"fewer elements in array"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
|
||||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
|
||||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
|
||||||
tuple_struct map struct enum identifier ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
|
||||||
where
|
|
||||||
T: de::DeserializeSeed<'de>,
|
|
||||||
{
|
|
||||||
match self.iter.next() {
|
|
||||||
Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some),
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> Option<usize> {
|
|
||||||
size_hint::from_bounds(&self.iter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MapDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
iter: <Vec<(Content<'de>, Content<'de>)> as IntoIterator>::IntoIter,
|
|
||||||
value: Option<Content<'de>>,
|
|
||||||
err: PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> MapDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self {
|
|
||||||
MapDeserializer {
|
|
||||||
iter: map.into_iter(),
|
|
||||||
value: None,
|
|
||||||
err: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
|
||||||
where
|
|
||||||
T: de::DeserializeSeed<'de>,
|
|
||||||
{
|
|
||||||
match self.iter.next() {
|
|
||||||
Some((key, value)) => {
|
|
||||||
self.value = Some(value);
|
|
||||||
seed.deserialize(ContentDeserializer::new(key)).map(Some)
|
|
||||||
}
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
|
||||||
where
|
|
||||||
T: de::DeserializeSeed<'de>,
|
|
||||||
{
|
|
||||||
match self.value.take() {
|
|
||||||
Some(value) => seed.deserialize(ContentDeserializer::new(value)),
|
|
||||||
None => Err(de::Error::custom("value is missing")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size_hint(&self) -> Option<usize> {
|
|
||||||
size_hint::from_bounds(&self.iter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E>
|
|
||||||
where
|
|
||||||
E: de::Error,
|
|
||||||
{
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where
|
|
||||||
V: de::Visitor<'de>,
|
|
||||||
{
|
|
||||||
visitor.visit_map(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
forward_to_deserialize_any! {
|
|
||||||
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
|
|
||||||
bytes byte_buf option unit unit_struct newtype_struct seq tuple
|
|
||||||
tuple_struct map struct enum identifier ignored_any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Not public API.
|
/// Not public API.
|
||||||
pub struct ContentRefDeserializer<'a, 'de: 'a, E> {
|
pub struct ContentRefDeserializer<'a, 'de: 'a, E> {
|
||||||
content: &'a Content<'de>,
|
content: &'a Content<'de>,
|
||||||
@@ -1820,9 +1684,9 @@ mod content {
|
|||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
let seq = content.iter().map(ContentRefDeserializer::new);
|
let seq = content.iter().map(ContentRefDeserializer::new);
|
||||||
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
|
let mut seq_visitor = SeqDeserializer::new(seq);
|
||||||
let value = try!(visitor.visit_seq(&mut seq_visitor));
|
let value = tri!(visitor.visit_seq(&mut seq_visitor));
|
||||||
try!(seq_visitor.end());
|
tri!(seq_visitor.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1840,9 +1704,9 @@ mod content {
|
|||||||
ContentRefDeserializer::new(v),
|
ContentRefDeserializer::new(v),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
let mut map_visitor = de::value::MapDeserializer::new(map);
|
let mut map_visitor = MapDeserializer::new(map);
|
||||||
let value = try!(visitor.visit_map(&mut map_visitor));
|
let value = tri!(visitor.visit_map(&mut map_visitor));
|
||||||
try!(map_visitor.end());
|
tri!(map_visitor.end());
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2362,7 +2226,7 @@ mod content {
|
|||||||
if len == 0 {
|
if len == 0 {
|
||||||
visitor.visit_unit()
|
visitor.visit_unit()
|
||||||
} else {
|
} else {
|
||||||
let ret = try!(visitor.visit_seq(&mut self));
|
let ret = tri!(visitor.visit_seq(&mut self));
|
||||||
let remaining = self.iter.len();
|
let remaining = self.iter.len();
|
||||||
if remaining == 0 {
|
if remaining == 0 {
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
@@ -2541,7 +2405,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
M: MapAccess<'de>,
|
M: MapAccess<'de>,
|
||||||
{
|
{
|
||||||
while try!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {}
|
while tri!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2974,3 +2838,55 @@ fn flat_map_take_entry<'de>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AdjacentlyTaggedEnumVariantSeed<F> {
|
||||||
|
pub enum_name: &'static str,
|
||||||
|
pub variants: &'static [&'static str],
|
||||||
|
pub fields_enum: PhantomData<F>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AdjacentlyTaggedEnumVariantVisitor<F> {
|
||||||
|
enum_name: &'static str,
|
||||||
|
fields_enum: PhantomData<F>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, F> Visitor<'de> for AdjacentlyTaggedEnumVariantVisitor<F>
|
||||||
|
where
|
||||||
|
F: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = F;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(formatter, "variant of enum {}", self.enum_name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||||
|
where
|
||||||
|
A: EnumAccess<'de>,
|
||||||
|
{
|
||||||
|
let (variant, variant_access) = tri!(data.variant());
|
||||||
|
tri!(variant_access.unit_variant());
|
||||||
|
Ok(variant)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariantSeed<F>
|
||||||
|
where
|
||||||
|
F: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
type Value = F;
|
||||||
|
|
||||||
|
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
deserializer.deserialize_enum(
|
||||||
|
self.enum_name,
|
||||||
|
self.variants,
|
||||||
|
AdjacentlyTaggedEnumVariantVisitor {
|
||||||
|
enum_name: self.enum_name,
|
||||||
|
fields_enum: PhantomData,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Used only by Serde doc tests. Not public API.
|
// Used only by Serde doc tests. Not public API.
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use ser;
|
use crate::ser;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
+11
-13
@@ -3,30 +3,28 @@ pub mod de;
|
|||||||
#[cfg(not(no_serde_derive))]
|
#[cfg(not(no_serde_derive))]
|
||||||
pub mod ser;
|
pub mod ser;
|
||||||
|
|
||||||
pub mod size_hint;
|
|
||||||
|
|
||||||
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
|
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
|
||||||
pub mod doc;
|
pub mod doc;
|
||||||
|
|
||||||
pub use lib::clone::Clone;
|
pub use crate::lib::clone::Clone;
|
||||||
pub use lib::convert::{From, Into};
|
pub use crate::lib::convert::{From, Into};
|
||||||
pub use lib::default::Default;
|
pub use crate::lib::default::Default;
|
||||||
pub use lib::fmt::{self, Formatter};
|
pub use crate::lib::fmt::{self, Formatter};
|
||||||
pub use lib::marker::PhantomData;
|
pub use crate::lib::marker::PhantomData;
|
||||||
pub use lib::option::Option::{self, None, Some};
|
pub use crate::lib::option::Option::{self, None, Some};
|
||||||
pub use lib::ptr;
|
pub use crate::lib::ptr;
|
||||||
pub use lib::result::Result::{self, Err, Ok};
|
pub use crate::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"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
pub use lib::{ToString, Vec};
|
pub use crate::lib::{ToString, Vec};
|
||||||
|
|
||||||
#[cfg(not(no_core_try_from))]
|
#[cfg(not(no_core_try_from))]
|
||||||
pub use lib::convert::TryFrom;
|
pub use crate::lib::convert::TryFrom;
|
||||||
|
|
||||||
mod string {
|
mod string {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
|
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
|
||||||
|
|||||||
+128
-66
@@ -1,6 +1,6 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
|
use crate::ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use self::content::{
|
use self::content::{
|
||||||
@@ -182,14 +182,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(1)));
|
let mut map = tri!(self.delegate.serialize_map(Some(1)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
|
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(1)));
|
let mut map = tri!(self.delegate.serialize_map(Some(1)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,9 +199,9 @@ where
|
|||||||
_: u32,
|
_: u32,
|
||||||
inner_variant: &'static str,
|
inner_variant: &'static str,
|
||||||
) -> Result<Self::Ok, Self::Error> {
|
) -> Result<Self::Ok, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = tri!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_entry(inner_variant, &()));
|
tri!(map.serialize_entry(inner_variant, &()));
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,9 +226,9 @@ where
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = tri!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_entry(inner_variant, inner_value));
|
tri!(map.serialize_entry(inner_variant, inner_value));
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,9 +269,9 @@ where
|
|||||||
inner_variant: &'static str,
|
inner_variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = tri!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_key(inner_variant));
|
tri!(map.serialize_key(inner_variant));
|
||||||
Ok(SerializeTupleVariantAsMapValue::new(
|
Ok(SerializeTupleVariantAsMapValue::new(
|
||||||
map,
|
map,
|
||||||
inner_variant,
|
inner_variant,
|
||||||
@@ -280,8 +280,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(len.map(|len| len + 1)));
|
let mut map = tri!(self.delegate.serialize_map(len.map(|len| len + 1)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
Ok(map)
|
Ok(map)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,8 +290,8 @@ where
|
|||||||
name: &'static str,
|
name: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||||
let mut state = try!(self.delegate.serialize_struct(name, len + 1));
|
let mut state = tri!(self.delegate.serialize_struct(name, len + 1));
|
||||||
try!(state.serialize_field(self.tag, self.variant_name));
|
tri!(state.serialize_field(self.tag, self.variant_name));
|
||||||
Ok(state)
|
Ok(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,9 +316,9 @@ where
|
|||||||
inner_variant: &'static str,
|
inner_variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||||
let mut map = try!(self.delegate.serialize_map(Some(2)));
|
let mut map = tri!(self.delegate.serialize_map(Some(2)));
|
||||||
try!(map.serialize_entry(self.tag, self.variant_name));
|
tri!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
try!(map.serialize_key(inner_variant));
|
tri!(map.serialize_key(inner_variant));
|
||||||
Ok(SerializeStructVariantAsMapValue::new(
|
Ok(SerializeStructVariantAsMapValue::new(
|
||||||
map,
|
map,
|
||||||
inner_variant,
|
inner_variant,
|
||||||
@@ -337,9 +337,9 @@ where
|
|||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
mod content {
|
mod content {
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use ser::{self, Serialize, Serializer};
|
use crate::ser::{self, Serialize, Serializer};
|
||||||
|
|
||||||
pub struct SerializeTupleVariantAsMapValue<M> {
|
pub struct SerializeTupleVariantAsMapValue<M> {
|
||||||
map: M,
|
map: M,
|
||||||
@@ -368,13 +368,13 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
|
||||||
self.fields.push(value);
|
self.fields.push(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(mut self) -> Result<M::Ok, M::Error> {
|
fn end(mut self) -> Result<M::Ok, M::Error> {
|
||||||
try!(self
|
tri!(self
|
||||||
.map
|
.map
|
||||||
.serialize_value(&Content::TupleStruct(self.name, self.fields)));
|
.serialize_value(&Content::TupleStruct(self.name, self.fields)));
|
||||||
self.map.end()
|
self.map.end()
|
||||||
@@ -412,13 +412,13 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
|
||||||
self.fields.push((key, value));
|
self.fields.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(mut self) -> Result<M::Ok, M::Error> {
|
fn end(mut self) -> Result<M::Ok, M::Error> {
|
||||||
try!(self
|
tri!(self
|
||||||
.map
|
.map
|
||||||
.serialize_value(&Content::Struct(self.name, self.fields)));
|
.serialize_value(&Content::Struct(self.name, self.fields)));
|
||||||
self.map.end()
|
self.map.end()
|
||||||
@@ -499,50 +499,50 @@ mod content {
|
|||||||
}
|
}
|
||||||
Content::Seq(ref elements) => elements.serialize(serializer),
|
Content::Seq(ref elements) => elements.serialize(serializer),
|
||||||
Content::Tuple(ref elements) => {
|
Content::Tuple(ref elements) => {
|
||||||
use ser::SerializeTuple;
|
use crate::ser::SerializeTuple;
|
||||||
let mut tuple = try!(serializer.serialize_tuple(elements.len()));
|
let mut tuple = tri!(serializer.serialize_tuple(elements.len()));
|
||||||
for e in elements {
|
for e in elements {
|
||||||
try!(tuple.serialize_element(e));
|
tri!(tuple.serialize_element(e));
|
||||||
}
|
}
|
||||||
tuple.end()
|
tuple.end()
|
||||||
}
|
}
|
||||||
Content::TupleStruct(n, ref fields) => {
|
Content::TupleStruct(n, ref fields) => {
|
||||||
use ser::SerializeTupleStruct;
|
use crate::ser::SerializeTupleStruct;
|
||||||
let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len()));
|
let mut ts = tri!(serializer.serialize_tuple_struct(n, fields.len()));
|
||||||
for f in fields {
|
for f in fields {
|
||||||
try!(ts.serialize_field(f));
|
tri!(ts.serialize_field(f));
|
||||||
}
|
}
|
||||||
ts.end()
|
ts.end()
|
||||||
}
|
}
|
||||||
Content::TupleVariant(n, i, v, ref fields) => {
|
Content::TupleVariant(n, i, v, ref fields) => {
|
||||||
use ser::SerializeTupleVariant;
|
use crate::ser::SerializeTupleVariant;
|
||||||
let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len()));
|
let mut tv = tri!(serializer.serialize_tuple_variant(n, i, v, fields.len()));
|
||||||
for f in fields {
|
for f in fields {
|
||||||
try!(tv.serialize_field(f));
|
tri!(tv.serialize_field(f));
|
||||||
}
|
}
|
||||||
tv.end()
|
tv.end()
|
||||||
}
|
}
|
||||||
Content::Map(ref entries) => {
|
Content::Map(ref entries) => {
|
||||||
use ser::SerializeMap;
|
use crate::ser::SerializeMap;
|
||||||
let mut map = try!(serializer.serialize_map(Some(entries.len())));
|
let mut map = tri!(serializer.serialize_map(Some(entries.len())));
|
||||||
for (k, v) in entries {
|
for (k, v) in entries {
|
||||||
try!(map.serialize_entry(k, v));
|
tri!(map.serialize_entry(k, v));
|
||||||
}
|
}
|
||||||
map.end()
|
map.end()
|
||||||
}
|
}
|
||||||
Content::Struct(n, ref fields) => {
|
Content::Struct(n, ref fields) => {
|
||||||
use ser::SerializeStruct;
|
use crate::ser::SerializeStruct;
|
||||||
let mut s = try!(serializer.serialize_struct(n, fields.len()));
|
let mut s = tri!(serializer.serialize_struct(n, fields.len()));
|
||||||
for &(k, ref v) in fields {
|
for &(k, ref v) in fields {
|
||||||
try!(s.serialize_field(k, v));
|
tri!(s.serialize_field(k, v));
|
||||||
}
|
}
|
||||||
s.end()
|
s.end()
|
||||||
}
|
}
|
||||||
Content::StructVariant(n, i, v, ref fields) => {
|
Content::StructVariant(n, i, v, ref fields) => {
|
||||||
use ser::SerializeStructVariant;
|
use crate::ser::SerializeStructVariant;
|
||||||
let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len()));
|
let mut sv = tri!(serializer.serialize_struct_variant(n, i, v, fields.len()));
|
||||||
for &(k, ref v) in fields {
|
for &(k, ref v) in fields {
|
||||||
try!(sv.serialize_field(k, v));
|
tri!(sv.serialize_field(k, v));
|
||||||
}
|
}
|
||||||
sv.end()
|
sv.end()
|
||||||
}
|
}
|
||||||
@@ -639,7 +639,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
Ok(Content::Some(Box::new(try!(value.serialize(self)))))
|
Ok(Content::Some(Box::new(tri!(value.serialize(self)))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Content, E> {
|
fn serialize_unit(self) -> Result<Content, E> {
|
||||||
@@ -669,7 +669,7 @@ mod content {
|
|||||||
{
|
{
|
||||||
Ok(Content::NewtypeStruct(
|
Ok(Content::NewtypeStruct(
|
||||||
name,
|
name,
|
||||||
Box::new(try!(value.serialize(self))),
|
Box::new(tri!(value.serialize(self))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@ mod content {
|
|||||||
name,
|
name,
|
||||||
variant_index,
|
variant_index,
|
||||||
variant,
|
variant,
|
||||||
Box::new(try!(value.serialize(self))),
|
Box::new(tri!(value.serialize(self))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,7 +786,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.elements.push(value);
|
self.elements.push(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -812,7 +812,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.elements.push(value);
|
self.elements.push(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -839,7 +839,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.fields.push(value);
|
self.fields.push(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -868,7 +868,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.fields.push(value);
|
self.fields.push(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -900,7 +900,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let key = try!(key.serialize(ContentSerializer::<E>::new()));
|
let key = tri!(key.serialize(ContentSerializer::<E>::new()));
|
||||||
self.key = Some(key);
|
self.key = Some(key);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -913,7 +913,7 @@ mod content {
|
|||||||
.key
|
.key
|
||||||
.take()
|
.take()
|
||||||
.expect("serialize_value called before serialize_key");
|
.expect("serialize_value called before serialize_key");
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.entries.push((key, value));
|
self.entries.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -927,8 +927,8 @@ mod content {
|
|||||||
K: Serialize,
|
K: Serialize,
|
||||||
V: Serialize,
|
V: Serialize,
|
||||||
{
|
{
|
||||||
let key = try!(key.serialize(ContentSerializer::<E>::new()));
|
let key = tri!(key.serialize(ContentSerializer::<E>::new()));
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.entries.push((key, value));
|
self.entries.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -951,7 +951,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.fields.push((key, value));
|
self.fields.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -980,7 +980,7 @@ mod content {
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<E>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<E>::new()));
|
||||||
self.fields.push((key, value));
|
self.fields.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1025,7 +1025,7 @@ where
|
|||||||
type SerializeTupleStruct = Impossible<Self::Ok, M::Error>;
|
type SerializeTupleStruct = Impossible<Self::Ok, M::Error>;
|
||||||
type SerializeMap = FlatMapSerializeMap<'a, M>;
|
type SerializeMap = FlatMapSerializeMap<'a, M>;
|
||||||
type SerializeStruct = FlatMapSerializeStruct<'a, M>;
|
type SerializeStruct = FlatMapSerializeStruct<'a, M>;
|
||||||
type SerializeTupleVariant = Impossible<Self::Ok, M::Error>;
|
type SerializeTupleVariant = FlatMapSerializeTupleVariantAsMapValue<'a, M>;
|
||||||
type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;
|
type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;
|
||||||
|
|
||||||
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
|
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
|
||||||
@@ -1133,7 +1133,7 @@ where
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
try!(self.0.serialize_key(variant));
|
tri!(self.0.serialize_key(variant));
|
||||||
self.0.serialize_value(value)
|
self.0.serialize_value(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1157,10 +1157,11 @@ where
|
|||||||
self,
|
self,
|
||||||
_: &'static str,
|
_: &'static str,
|
||||||
_: u32,
|
_: u32,
|
||||||
_: &'static str,
|
variant: &'static str,
|
||||||
_: usize,
|
_: usize,
|
||||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||||
Err(Self::bad_type(Unsupported::Enum))
|
tri!(self.0.serialize_key(variant));
|
||||||
|
Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||||
@@ -1182,7 +1183,7 @@ where
|
|||||||
inner_variant: &'static str,
|
inner_variant: &'static str,
|
||||||
_: usize,
|
_: usize,
|
||||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||||
try!(self.0.serialize_key(inner_variant));
|
tri!(self.0.serialize_key(inner_variant));
|
||||||
Ok(FlatMapSerializeStructVariantAsMapValue::new(
|
Ok(FlatMapSerializeStructVariantAsMapValue::new(
|
||||||
self.0,
|
self.0,
|
||||||
inner_variant,
|
inner_variant,
|
||||||
@@ -1259,6 +1260,52 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
pub struct FlatMapSerializeTupleVariantAsMapValue<'a, M: 'a> {
|
||||||
|
map: &'a mut M,
|
||||||
|
fields: Vec<Content>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, M> FlatMapSerializeTupleVariantAsMapValue<'a, M>
|
||||||
|
where
|
||||||
|
M: SerializeMap + 'a,
|
||||||
|
{
|
||||||
|
fn new(map: &'a mut M) -> Self {
|
||||||
|
FlatMapSerializeTupleVariantAsMapValue {
|
||||||
|
map,
|
||||||
|
fields: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M>
|
||||||
|
where
|
||||||
|
M: SerializeMap + 'a,
|
||||||
|
{
|
||||||
|
type Ok = ();
|
||||||
|
type Error = M::Error;
|
||||||
|
|
||||||
|
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
|
||||||
|
self.fields.push(value);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<(), Self::Error> {
|
||||||
|
tri!(self.map.serialize_value(&Content::Seq(self.fields)));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> {
|
pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> {
|
||||||
map: &'a mut M,
|
map: &'a mut M,
|
||||||
@@ -1296,15 +1343,30 @@ where
|
|||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
|
let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
|
||||||
self.fields.push((key, value));
|
self.fields.push((key, value));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<(), Self::Error> {
|
fn end(self) -> Result<(), Self::Error> {
|
||||||
try!(self
|
tri!(self
|
||||||
.map
|
.map
|
||||||
.serialize_value(&Content::Struct(self.name, self.fields)));
|
.serialize_value(&Content::Struct(self.name, self.fields)));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct AdjacentlyTaggedEnumVariant {
|
||||||
|
pub enum_name: &'static str,
|
||||||
|
pub variant_index: u32,
|
||||||
|
pub variant_name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for AdjacentlyTaggedEnumVariant {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_unit_variant(self.enum_name, self.variant_index, self.variant_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
use ser::{Error, Impossible, Serialize, Serializer};
|
use crate::ser::{Error, Impossible, Serialize, Serializer};
|
||||||
|
|
||||||
impl Error for fmt::Error {
|
impl Error for fmt::Error {
|
||||||
fn custom<T: Display>(_msg: T) -> Self {
|
fn custom<T: Display>(_msg: T) -> Self {
|
||||||
|
|||||||
+23
-28
@@ -1,6 +1,6 @@
|
|||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use ser::{Error, Serialize, SerializeTuple, Serializer};
|
use crate::ser::{Error, Serialize, SerializeTuple, Serializer};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ impl<T> Serialize for [T; 0] {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
try!(serializer.serialize_tuple(0)).end()
|
tri!(serializer.serialize_tuple(0)).end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,9 +149,9 @@ macro_rules! array_impls {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut seq = try!(serializer.serialize_tuple($len));
|
let mut seq = tri!(serializer.serialize_tuple($len));
|
||||||
for e in self {
|
for e in self {
|
||||||
try!(seq.serialize_element(e));
|
tri!(seq.serialize_element(e));
|
||||||
}
|
}
|
||||||
seq.end()
|
seq.end()
|
||||||
}
|
}
|
||||||
@@ -248,9 +248,9 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("Range", 2));
|
let mut state = tri!(serializer.serialize_struct("Range", 2));
|
||||||
try!(state.serialize_field("start", &self.start));
|
tri!(state.serialize_field("start", &self.start));
|
||||||
try!(state.serialize_field("end", &self.end));
|
tri!(state.serialize_field("end", &self.end));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,15 +266,14 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("RangeFrom", 1));
|
let mut state = tri!(serializer.serialize_struct("RangeFrom", 1));
|
||||||
try!(state.serialize_field("start", &self.start));
|
tri!(state.serialize_field("start", &self.start));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(not(no_range_inclusive))]
|
|
||||||
impl<Idx> Serialize for RangeInclusive<Idx>
|
impl<Idx> Serialize for RangeInclusive<Idx>
|
||||||
where
|
where
|
||||||
Idx: Serialize,
|
Idx: Serialize,
|
||||||
@@ -284,9 +283,9 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("RangeInclusive", 2));
|
let mut state = tri!(serializer.serialize_struct("RangeInclusive", 2));
|
||||||
try!(state.serialize_field("start", &self.start()));
|
tri!(state.serialize_field("start", &self.start()));
|
||||||
try!(state.serialize_field("end", &self.end()));
|
tri!(state.serialize_field("end", &self.end()));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -302,15 +301,14 @@ where
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("RangeTo", 1));
|
let mut state = tri!(serializer.serialize_struct("RangeTo", 1));
|
||||||
try!(state.serialize_field("end", &self.end));
|
tri!(state.serialize_field("end", &self.end));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
|
|
||||||
impl<T> Serialize for Bound<T>
|
impl<T> Serialize for Bound<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
@@ -367,9 +365,9 @@ macro_rules! tuple_impls {
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut tuple = try!(serializer.serialize_tuple($len));
|
let mut tuple = tri!(serializer.serialize_tuple($len));
|
||||||
$(
|
$(
|
||||||
try!(tuple.serialize_element(&self.$n));
|
tri!(tuple.serialize_element(&self.$n));
|
||||||
)+
|
)+
|
||||||
tuple.end()
|
tuple.end()
|
||||||
}
|
}
|
||||||
@@ -538,7 +536,6 @@ where
|
|||||||
macro_rules! nonzero_integers {
|
macro_rules! nonzero_integers {
|
||||||
($($T:ident,)+) => {
|
($($T:ident,)+) => {
|
||||||
$(
|
$(
|
||||||
#[cfg(not(no_num_nonzero))]
|
|
||||||
impl Serialize for num::$T {
|
impl Serialize for num::$T {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
@@ -662,16 +659,15 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[cfg(any(feature = "std", not(no_core_duration)))]
|
|
||||||
impl Serialize for Duration {
|
impl Serialize for Duration {
|
||||||
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,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let mut state = try!(serializer.serialize_struct("Duration", 2));
|
let mut state = tri!(serializer.serialize_struct("Duration", 2));
|
||||||
try!(state.serialize_field("secs", &self.as_secs()));
|
tri!(state.serialize_field("secs", &self.as_secs()));
|
||||||
try!(state.serialize_field("nanos", &self.subsec_nanos()));
|
tri!(state.serialize_field("nanos", &self.subsec_nanos()));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -689,9 +685,9 @@ impl Serialize for SystemTime {
|
|||||||
Ok(duration_since_epoch) => duration_since_epoch,
|
Ok(duration_since_epoch) => duration_since_epoch,
|
||||||
Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
|
Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
|
||||||
};
|
};
|
||||||
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
let mut state = tri!(serializer.serialize_struct("SystemTime", 2));
|
||||||
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
tri!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||||
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
tri!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -963,7 +959,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(no_core_reverse))]
|
|
||||||
impl<T> Serialize for Reverse<T>
|
impl<T> Serialize for Reverse<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
//! This module contains `Impossible` serializer and its implementations.
|
//! This module contains `Impossible` serializer and its implementations.
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
use ser::{
|
use crate::ser::{
|
||||||
self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
|
||||||
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
|
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
|
||||||
};
|
};
|
||||||
|
|||||||
+11
-37
@@ -107,7 +107,7 @@
|
|||||||
//! [derive section of the manual]: https://serde.rs/derive.html
|
//! [derive section of the manual]: https://serde.rs/derive.html
|
||||||
//! [data formats]: https://serde.rs/#data-formats
|
//! [data formats]: https://serde.rs/#data-formats
|
||||||
|
|
||||||
use lib::*;
|
use crate::lib::*;
|
||||||
|
|
||||||
mod fmt;
|
mod fmt;
|
||||||
mod impls;
|
mod impls;
|
||||||
@@ -115,15 +115,15 @@ mod impossible;
|
|||||||
|
|
||||||
pub use self::impossible::Impossible;
|
pub use self::impossible::Impossible;
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "std", feature = "unstable")))]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::std_error::Error as StdError;
|
||||||
#[cfg(all(feature = "unstable", not(feature = "std")))]
|
#[cfg(all(feature = "unstable", not(feature = "std")))]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use core::error::Error as StdError;
|
pub use core::error::Error as StdError;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use std::error::Error as StdError;
|
pub use std::error::Error as StdError;
|
||||||
#[cfg(not(any(feature = "std", feature = "unstable")))]
|
|
||||||
#[doc(no_inline)]
|
|
||||||
pub use std_error::Error as StdError;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -1279,22 +1279,9 @@ pub trait Serializer: Sized {
|
|||||||
I: IntoIterator,
|
I: IntoIterator,
|
||||||
<I as IntoIterator>::Item: Serialize,
|
<I as IntoIterator>::Item: Serialize,
|
||||||
{
|
{
|
||||||
let iter = iter.into_iter();
|
let mut iter = iter.into_iter();
|
||||||
let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter)));
|
let mut serializer = tri!(self.serialize_seq(iterator_len_hint(&iter)));
|
||||||
|
tri!(iter.try_for_each(|item| serializer.serialize_element(&item)));
|
||||||
#[cfg(not(no_iterator_try_fold))]
|
|
||||||
{
|
|
||||||
let mut iter = iter;
|
|
||||||
try!(iter.try_for_each(|item| serializer.serialize_element(&item)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(no_iterator_try_fold)]
|
|
||||||
{
|
|
||||||
for item in iter {
|
|
||||||
try!(serializer.serialize_element(&item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.end()
|
serializer.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1330,22 +1317,9 @@ pub trait Serializer: Sized {
|
|||||||
V: Serialize,
|
V: Serialize,
|
||||||
I: IntoIterator<Item = (K, V)>,
|
I: IntoIterator<Item = (K, V)>,
|
||||||
{
|
{
|
||||||
let iter = iter.into_iter();
|
let mut iter = iter.into_iter();
|
||||||
let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter)));
|
let mut serializer = tri!(self.serialize_map(iterator_len_hint(&iter)));
|
||||||
|
tri!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
|
||||||
#[cfg(not(no_iterator_try_fold))]
|
|
||||||
{
|
|
||||||
let mut iter = iter;
|
|
||||||
try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(no_iterator_try_fold)]
|
|
||||||
{
|
|
||||||
for (key, value) in iter {
|
|
||||||
try!(serializer.serialize_entry(&key, &value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serializer.end()
|
serializer.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1839,7 +1813,7 @@ pub trait SerializeMap {
|
|||||||
K: Serialize,
|
K: Serialize,
|
||||||
V: Serialize,
|
V: Serialize,
|
||||||
{
|
{
|
||||||
try!(self.serialize_key(key));
|
tri!(self.serialize_key(key));
|
||||||
self.serialize_value(value)
|
self.serialize_value(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use lib::{Debug, Display};
|
use crate::lib::{Debug, Display};
|
||||||
|
|
||||||
/// Either a re-export of std::error::Error or a new identical trait, depending
|
/// Either a re-export of std::error::Error or a new identical trait, depending
|
||||||
/// on whether Serde's "std" feature is enabled.
|
/// on whether Serde's "std" feature is enabled.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.178" # remember to update html_root_url
|
version = "1.0.183" # 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>"]
|
||||||
categories = ["no-std", "no-std::no-alloc"]
|
categories = ["no-std", "no-std::no-alloc"]
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
@@ -23,7 +23,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = "2.0.25"
|
syn = "2.0.28"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1", path = "../serde" }
|
serde = { version = "1", path = "../serde" }
|
||||||
|
|||||||
+184
-231
@@ -324,10 +324,10 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
|
|||||||
|
|
||||||
let code = match &cont.data {
|
let code = match &cont.data {
|
||||||
Data::Struct(Style::Struct, fields) => {
|
Data::Struct(Style::Struct, fields) => {
|
||||||
deserialize_struct_in_place(None, params, fields, &cont.attrs, None)?
|
deserialize_struct_in_place(params, fields, &cont.attrs)?
|
||||||
}
|
}
|
||||||
Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
|
Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
|
||||||
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
|
deserialize_tuple_in_place(params, fields, &cont.attrs)
|
||||||
}
|
}
|
||||||
Data::Enum(_) | Data::Struct(Style::Unit, _) => {
|
Data::Enum(_) | Data::Struct(Style::Unit, _) => {
|
||||||
return None;
|
return None;
|
||||||
@@ -582,11 +582,9 @@ fn deserialize_tuple(
|
|||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_tuple_in_place(
|
fn deserialize_tuple_in_place(
|
||||||
variant_ident: Option<syn::Ident>,
|
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
deserializer: Option<TokenStream>,
|
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
assert!(!cattrs.has_flatten());
|
assert!(!cattrs.has_flatten());
|
||||||
|
|
||||||
@@ -600,17 +598,25 @@ fn deserialize_tuple_in_place(
|
|||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let is_enum = variant_ident.is_some();
|
let expecting = format!("tuple struct {}", params.type_name());
|
||||||
let expecting = match variant_ident {
|
|
||||||
Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
|
|
||||||
None => format!("tuple struct {}", params.type_name()),
|
|
||||||
};
|
|
||||||
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
||||||
|
|
||||||
let nfields = fields.len();
|
let nfields = fields.len();
|
||||||
|
|
||||||
let visit_newtype_struct = if !is_enum && nfields == 1 {
|
let visit_newtype_struct = if nfields == 1 {
|
||||||
Some(deserialize_newtype_struct_in_place(params, &fields[0]))
|
// We do not generate deserialize_in_place if every field has a
|
||||||
|
// deserialize_with.
|
||||||
|
assert!(fields[0].attrs.deserialize_with().is_none());
|
||||||
|
|
||||||
|
Some(quote! {
|
||||||
|
#[inline]
|
||||||
|
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
|
||||||
|
where
|
||||||
|
__E: _serde::Deserializer<#delife>,
|
||||||
|
{
|
||||||
|
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -624,15 +630,10 @@ fn deserialize_tuple_in_place(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let dispatch = if let Some(deserializer) = deserializer {
|
let type_name = cattrs.name().deserialize_name();
|
||||||
quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #field_count, #visitor_expr))
|
let dispatch = if nfields == 1 {
|
||||||
} else if is_enum {
|
|
||||||
quote!(_serde::de::VariantAccess::tuple_variant(__variant, #field_count, #visitor_expr))
|
|
||||||
} else if nfields == 1 {
|
|
||||||
let type_name = cattrs.name().deserialize_name();
|
|
||||||
quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
|
quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
|
||||||
} else {
|
} else {
|
||||||
let type_name = cattrs.name().deserialize_name();
|
|
||||||
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr))
|
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -722,19 +723,11 @@ fn deserialize_seq(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let value_if_none = match field.attrs.default() {
|
let value_if_none = expr_is_missing_seq(None, index_in_seq, field, cattrs, expecting);
|
||||||
attr::Default::Default => quote!(_serde::__private::Default::default()),
|
|
||||||
attr::Default::Path(path) => quote!(#path()),
|
|
||||||
attr::Default::None => quote!(
|
|
||||||
return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let assign = quote! {
|
let assign = quote! {
|
||||||
let #var = match #visit {
|
let #var = match #visit {
|
||||||
_serde::__private::Some(__value) => __value,
|
_serde::__private::Some(__value) => __value,
|
||||||
_serde::__private::None => {
|
_serde::__private::None => #value_if_none,
|
||||||
#value_if_none
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
index_in_seq += 1;
|
index_in_seq += 1;
|
||||||
@@ -810,24 +803,14 @@ fn deserialize_seq_in_place(
|
|||||||
self.place.#member = #default;
|
self.place.#member = #default;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let value_if_none = match field.attrs.default() {
|
let value_if_none = expr_is_missing_seq(Some(quote!(self.place.#member = )), index_in_seq, field, cattrs, expecting);
|
||||||
attr::Default::Default => quote!(
|
|
||||||
self.place.#member = _serde::__private::Default::default();
|
|
||||||
),
|
|
||||||
attr::Default::Path(path) => quote!(
|
|
||||||
self.place.#member = #path();
|
|
||||||
),
|
|
||||||
attr::Default::None => quote!(
|
|
||||||
return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
|
|
||||||
),
|
|
||||||
};
|
|
||||||
let write = match field.attrs.deserialize_with() {
|
let write = match field.attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq,
|
if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq,
|
||||||
_serde::__private::de::InPlaceSeed(&mut self.place.#member))?
|
_serde::__private::de::InPlaceSeed(&mut self.place.#member))?
|
||||||
{
|
{
|
||||||
#value_if_none
|
#value_if_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -840,7 +823,7 @@ fn deserialize_seq_in_place(
|
|||||||
self.place.#member = __wrap.value;
|
self.place.#member = __wrap.value;
|
||||||
}
|
}
|
||||||
_serde::__private::None => {
|
_serde::__private::None => {
|
||||||
#value_if_none
|
#value_if_none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -918,25 +901,6 @@ fn deserialize_newtype_struct(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
|
||||||
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
|
|
||||||
// We do not generate deserialize_in_place if every field has a
|
|
||||||
// deserialize_with.
|
|
||||||
assert!(field.attrs.deserialize_with().is_none());
|
|
||||||
|
|
||||||
let delife = params.borrowed.de_lifetime();
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#[inline]
|
|
||||||
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
|
|
||||||
where
|
|
||||||
__E: _serde::Deserializer<#delife>,
|
|
||||||
{
|
|
||||||
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum StructForm<'a> {
|
enum StructForm<'a> {
|
||||||
Struct,
|
Struct,
|
||||||
/// Contains a variant name
|
/// Contains a variant name
|
||||||
@@ -1001,12 +965,7 @@ fn deserialize_struct(
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let field_visitor = Stmts(deserialize_generated_identifier(
|
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
|
||||||
&field_names_idents,
|
|
||||||
cattrs,
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
// untagged struct variants do not get a visit_seq method. The same applies to
|
// untagged struct variants do not get a visit_seq method. The same applies to
|
||||||
// structs that only have a map representation.
|
// structs that only have a map representation.
|
||||||
@@ -1058,7 +1017,7 @@ fn deserialize_struct(
|
|||||||
} else {
|
} else {
|
||||||
let field_names = field_names_idents
|
let field_names = field_names_idents
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(_, _, aliases)| aliases);
|
.flat_map(|&(_, _, aliases)| aliases);
|
||||||
|
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@@ -1133,14 +1092,10 @@ fn deserialize_struct(
|
|||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_struct_in_place(
|
fn deserialize_struct_in_place(
|
||||||
variant_ident: Option<syn::Ident>,
|
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
deserializer: Option<TokenStream>,
|
|
||||||
) -> Option<Fragment> {
|
) -> Option<Fragment> {
|
||||||
let is_enum = variant_ident.is_some();
|
|
||||||
|
|
||||||
// for now we do not support in_place deserialization for structs that
|
// for now we do not support in_place deserialization for structs that
|
||||||
// are represented as map.
|
// are represented as map.
|
||||||
if cattrs.has_flatten() {
|
if cattrs.has_flatten() {
|
||||||
@@ -1152,58 +1107,35 @@ fn deserialize_struct_in_place(
|
|||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
|
|
||||||
let expecting = match variant_ident {
|
let expecting = format!("struct {}", params.type_name());
|
||||||
Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
|
|
||||||
None => format!("struct {}", params.type_name()),
|
|
||||||
};
|
|
||||||
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
||||||
|
|
||||||
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
|
let field_names_idents: Vec<_> = fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
||||||
|
.map(|(i, field)| {
|
||||||
|
(
|
||||||
|
field.attrs.name().deserialize_name(),
|
||||||
|
field_i(i),
|
||||||
|
field.attrs.aliases(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let (field_visitor, fields_stmt, visit_map) =
|
let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs);
|
||||||
deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs);
|
|
||||||
|
|
||||||
let field_visitor = Stmts(field_visitor);
|
let mut_seq = if field_names_idents.is_empty() {
|
||||||
let fields_stmt = Stmts(fields_stmt);
|
|
||||||
let visit_map = Stmts(visit_map);
|
|
||||||
|
|
||||||
let visitor_expr = quote! {
|
|
||||||
__Visitor {
|
|
||||||
place: __place,
|
|
||||||
lifetime: _serde::__private::PhantomData,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let dispatch = if let Some(deserializer) = deserializer {
|
|
||||||
quote! {
|
|
||||||
_serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
|
|
||||||
}
|
|
||||||
} else if is_enum {
|
|
||||||
quote! {
|
|
||||||
_serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let type_name = cattrs.name().deserialize_name();
|
|
||||||
quote! {
|
|
||||||
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
|
|
||||||
let visitor_var = if all_skipped {
|
|
||||||
quote!(_)
|
quote!(_)
|
||||||
} else {
|
} else {
|
||||||
quote!(mut __seq)
|
quote!(mut __seq)
|
||||||
};
|
};
|
||||||
|
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
|
||||||
let visit_seq = quote! {
|
let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
|
||||||
#[inline]
|
let field_names = field_names_idents
|
||||||
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error>
|
.iter()
|
||||||
where
|
.flat_map(|&(_, _, aliases)| aliases);
|
||||||
__A: _serde::de::SeqAccess<#delife>,
|
let type_name = cattrs.name().deserialize_name();
|
||||||
{
|
|
||||||
#visit_seq
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let in_place_impl_generics = de_impl_generics.in_place();
|
let in_place_impl_generics = de_impl_generics.in_place();
|
||||||
let in_place_ty_generics = de_ty_generics.in_place();
|
let in_place_ty_generics = de_ty_generics.in_place();
|
||||||
@@ -1225,7 +1157,13 @@ fn deserialize_struct_in_place(
|
|||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
}
|
}
|
||||||
|
|
||||||
#visit_seq
|
#[inline]
|
||||||
|
fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||||
|
where
|
||||||
|
__A: _serde::de::SeqAccess<#delife>,
|
||||||
|
{
|
||||||
|
#visit_seq
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
|
fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
|
||||||
@@ -1236,9 +1174,13 @@ fn deserialize_struct_in_place(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#fields_stmt
|
#[doc(hidden)]
|
||||||
|
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
||||||
|
|
||||||
#dispatch
|
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor {
|
||||||
|
place: __place,
|
||||||
|
lifetime: _serde::__private::PhantomData,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,7 +1237,12 @@ fn prepare_enum_variant_enum(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other());
|
let fallthrough = deserialized_variants
|
||||||
|
.position(|(_, variant)| variant.attrs.other())
|
||||||
|
.map(|other_idx| {
|
||||||
|
let ignore_variant = variant_names_idents[other_idx].1.clone();
|
||||||
|
quote!(_serde::__private::Ok(__Field::#ignore_variant))
|
||||||
|
});
|
||||||
|
|
||||||
let variants_stmt = {
|
let variants_stmt = {
|
||||||
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
|
let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
|
||||||
@@ -1309,7 +1256,8 @@ fn prepare_enum_variant_enum(
|
|||||||
&variant_names_idents,
|
&variant_names_idents,
|
||||||
cattrs,
|
cattrs,
|
||||||
true,
|
true,
|
||||||
other_idx,
|
None,
|
||||||
|
fallthrough,
|
||||||
));
|
));
|
||||||
|
|
||||||
(variants_stmt, variant_visitor)
|
(variants_stmt, variant_visitor)
|
||||||
@@ -1490,7 +1438,8 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let expecting = format!("adjacently tagged enum {}", params.type_name());
|
let rust_name = params.type_name();
|
||||||
|
let expecting = format!("adjacently tagged enum {}", rust_name);
|
||||||
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
let expecting = cattrs.expecting().unwrap_or(&expecting);
|
||||||
let type_name = cattrs.name().deserialize_name();
|
let type_name = cattrs.name().deserialize_name();
|
||||||
let deny_unknown_fields = cattrs.deny_unknown_fields();
|
let deny_unknown_fields = cattrs.deny_unknown_fields();
|
||||||
@@ -1510,6 +1459,14 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let variant_seed = quote! {
|
||||||
|
_serde::__private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
|
||||||
|
enum_name: #rust_name,
|
||||||
|
variants: VARIANTS,
|
||||||
|
fields_enum: _serde::__private::PhantomData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut missing_content = quote! {
|
let mut missing_content = quote! {
|
||||||
_serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
|
_serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
|
||||||
};
|
};
|
||||||
@@ -1557,6 +1514,10 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)?
|
_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let variant_from_map = quote! {
|
||||||
|
_serde::de::MapAccess::next_value_seed(&mut __map, #variant_seed)?
|
||||||
|
};
|
||||||
|
|
||||||
// When allowing unknown fields, we want to transparently step through keys
|
// When allowing unknown fields, we want to transparently step through keys
|
||||||
// we don't care about until we find `tag`, `content`, or run out of keys.
|
// we don't care about until we find `tag`, `content`, or run out of keys.
|
||||||
let next_relevant_key = if deny_unknown_fields {
|
let next_relevant_key = if deny_unknown_fields {
|
||||||
@@ -1602,11 +1563,11 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
|
|
||||||
let finish_content_then_tag = if variant_arms.is_empty() {
|
let finish_content_then_tag = if variant_arms.is_empty() {
|
||||||
quote! {
|
quote! {
|
||||||
match _serde::de::MapAccess::next_value::<__Field>(&mut __map)? {}
|
match #variant_from_map {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
let __ret = match _serde::de::MapAccess::next_value(&mut __map)? {
|
let __ret = match #variant_from_map {
|
||||||
// Deserialize the buffered content now that we know the variant.
|
// Deserialize the buffered content now that we know the variant.
|
||||||
#(#variant_arms)*
|
#(#variant_arms)*
|
||||||
}?;
|
}?;
|
||||||
@@ -1662,7 +1623,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
// First key is the tag.
|
// First key is the tag.
|
||||||
_serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
|
_serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
|
||||||
// Parse the tag.
|
// Parse the tag.
|
||||||
let __field = _serde::de::MapAccess::next_value(&mut __map)?;
|
let __field = #variant_from_map;
|
||||||
// Visit the second key.
|
// Visit the second key.
|
||||||
match #next_relevant_key {
|
match #next_relevant_key {
|
||||||
// Second key is a duplicate of the tag.
|
// Second key is a duplicate of the tag.
|
||||||
@@ -2018,30 +1979,15 @@ fn deserialize_untagged_newtype_variant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_generated_identifier(
|
fn deserialize_generated_identifier(
|
||||||
fields: &[(String, Ident, Vec<String>)],
|
fields: &[(&str, Ident, &BTreeSet<String>)],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
other_idx: Option<usize>,
|
ignore_variant: Option<TokenStream>,
|
||||||
|
fallthrough: Option<TokenStream>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this_value = quote!(__Field);
|
let this_value = quote!(__Field);
|
||||||
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
|
let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
|
||||||
|
|
||||||
let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
|
|
||||||
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
|
||||||
} else if let Some(other_idx) = other_idx {
|
|
||||||
let ignore_variant = fields[other_idx].1.clone();
|
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
|
|
||||||
(None, Some(fallthrough))
|
|
||||||
} else if is_variant || cattrs.deny_unknown_fields() {
|
|
||||||
(None, None)
|
|
||||||
} else {
|
|
||||||
let ignore_variant = quote!(__ignore,);
|
|
||||||
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
|
||||||
(Some(ignore_variant), Some(fallthrough))
|
|
||||||
};
|
|
||||||
|
|
||||||
let visitor_impl = Stmts(deserialize_identifier(
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
&this_value,
|
&this_value,
|
||||||
fields,
|
fields,
|
||||||
@@ -2087,6 +2033,33 @@ fn deserialize_generated_identifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates enum and its `Deserialize` implementation that represents each
|
||||||
|
/// non-skipped field of the struct
|
||||||
|
fn deserialize_field_identifier(
|
||||||
|
fields: &[(&str, Ident, &BTreeSet<String>)],
|
||||||
|
cattrs: &attr::Container,
|
||||||
|
) -> Stmts {
|
||||||
|
let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
|
||||||
|
let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
|
||||||
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
|
||||||
|
(Some(ignore_variant), Some(fallthrough))
|
||||||
|
} else if cattrs.deny_unknown_fields() {
|
||||||
|
(None, None)
|
||||||
|
} else {
|
||||||
|
let ignore_variant = quote!(__ignore,);
|
||||||
|
let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
|
||||||
|
(Some(ignore_variant), Some(fallthrough))
|
||||||
|
};
|
||||||
|
|
||||||
|
Stmts(deserialize_generated_identifier(
|
||||||
|
fields,
|
||||||
|
cattrs,
|
||||||
|
false,
|
||||||
|
ignore_variant,
|
||||||
|
fallthrough,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
// Generates `Deserialize::deserialize` body for an enum with
|
// Generates `Deserialize::deserialize` body for an enum with
|
||||||
// `serde(field_identifier)` or `serde(variant_identifier)` attribute.
|
// `serde(field_identifier)` or `serde(variant_identifier)` attribute.
|
||||||
fn deserialize_custom_identifier(
|
fn deserialize_custom_identifier(
|
||||||
@@ -2148,7 +2121,7 @@ fn deserialize_custom_identifier(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let names = names_idents.iter().map(|(name, _, _)| name);
|
let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases);
|
||||||
|
|
||||||
let names_const = if fallthrough.is_some() {
|
let names_const = if fallthrough.is_some() {
|
||||||
None
|
None
|
||||||
@@ -2204,32 +2177,24 @@ fn deserialize_custom_identifier(
|
|||||||
|
|
||||||
fn deserialize_identifier(
|
fn deserialize_identifier(
|
||||||
this_value: &TokenStream,
|
this_value: &TokenStream,
|
||||||
fields: &[(String, Ident, Vec<String>)],
|
fields: &[(&str, Ident, &BTreeSet<String>)],
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
fallthrough: Option<TokenStream>,
|
fallthrough: Option<TokenStream>,
|
||||||
fallthrough_borrowed: Option<TokenStream>,
|
fallthrough_borrowed: Option<TokenStream>,
|
||||||
collect_other_fields: bool,
|
collect_other_fields: bool,
|
||||||
expecting: Option<&str>,
|
expecting: Option<&str>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let mut flat_fields = Vec::new();
|
let str_mapping = fields.iter().map(|(_, ident, aliases)| {
|
||||||
for (_, ident, aliases) in fields {
|
// `aliases` also contains a main name
|
||||||
flat_fields.extend(aliases.iter().map(|alias| (alias, ident)));
|
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
||||||
}
|
});
|
||||||
|
let bytes_mapping = fields.iter().map(|(_, ident, aliases)| {
|
||||||
let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect();
|
// `aliases` also contains a main name
|
||||||
let field_bytes: &Vec<_> = &flat_fields
|
let aliases = aliases
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(name, _)| Literal::byte_string(name.as_bytes()))
|
.map(|alias| Literal::byte_string(alias.as_bytes()));
|
||||||
.collect();
|
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
||||||
|
});
|
||||||
let constructors: &Vec<_> = &flat_fields
|
|
||||||
.iter()
|
|
||||||
.map(|(_, ident)| quote!(#this_value::#ident))
|
|
||||||
.collect();
|
|
||||||
let main_constructors: &Vec<_> = &fields
|
|
||||||
.iter()
|
|
||||||
.map(|(_, ident, _)| quote!(#this_value::#ident))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let expecting = expecting.unwrap_or(if is_variant {
|
let expecting = expecting.unwrap_or(if is_variant {
|
||||||
"variant identifier"
|
"variant identifier"
|
||||||
@@ -2237,8 +2202,6 @@ fn deserialize_identifier(
|
|||||||
"field identifier"
|
"field identifier"
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_expecting = if is_variant { "variant" } else { "field" };
|
|
||||||
|
|
||||||
let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
|
let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -2286,21 +2249,6 @@ fn deserialize_identifier(
|
|||||||
&fallthrough_arm_tokens
|
&fallthrough_arm_tokens
|
||||||
};
|
};
|
||||||
|
|
||||||
let u64_fallthrough_arm_tokens;
|
|
||||||
let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
|
|
||||||
fallthrough
|
|
||||||
} else {
|
|
||||||
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
|
||||||
u64_fallthrough_arm_tokens = quote! {
|
|
||||||
_serde::__private::Err(_serde::de::Error::invalid_value(
|
|
||||||
_serde::de::Unexpected::Unsigned(__value),
|
|
||||||
&#fallthrough_msg,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
&u64_fallthrough_arm_tokens
|
|
||||||
};
|
|
||||||
|
|
||||||
let variant_indices = 0_u64..;
|
|
||||||
let visit_other = if collect_other_fields {
|
let visit_other = if collect_other_fields {
|
||||||
quote! {
|
quote! {
|
||||||
fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E>
|
fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E>
|
||||||
@@ -2395,15 +2343,33 @@ fn deserialize_identifier(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| {
|
||||||
|
let i = i as u64;
|
||||||
|
quote!(#i => _serde::__private::Ok(#this_value::#ident))
|
||||||
|
});
|
||||||
|
|
||||||
|
let u64_fallthrough_arm_tokens;
|
||||||
|
let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
|
||||||
|
fallthrough
|
||||||
|
} else {
|
||||||
|
let index_expecting = if is_variant { "variant" } else { "field" };
|
||||||
|
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
|
||||||
|
u64_fallthrough_arm_tokens = quote! {
|
||||||
|
_serde::__private::Err(_serde::de::Error::invalid_value(
|
||||||
|
_serde::de::Unexpected::Unsigned(__value),
|
||||||
|
&#fallthrough_msg,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
&u64_fallthrough_arm_tokens
|
||||||
|
};
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
|
||||||
where
|
where
|
||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
match __value {
|
match __value {
|
||||||
#(
|
#(#u64_mapping,)*
|
||||||
#variant_indices => _serde::__private::Ok(#main_constructors),
|
|
||||||
)*
|
|
||||||
_ => #u64_fallthrough_arm,
|
_ => #u64_fallthrough_arm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2411,6 +2377,8 @@ fn deserialize_identifier(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
|
let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
|
||||||
|
let str_mapping = str_mapping.clone();
|
||||||
|
let bytes_mapping = bytes_mapping.clone();
|
||||||
let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
|
let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
|
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
|
||||||
@@ -2418,9 +2386,7 @@ fn deserialize_identifier(
|
|||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
match __value {
|
match __value {
|
||||||
#(
|
#(#str_mapping,)*
|
||||||
#field_strs => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
_ => {
|
||||||
#value_as_borrowed_str_content
|
#value_as_borrowed_str_content
|
||||||
#fallthrough_borrowed_arm
|
#fallthrough_borrowed_arm
|
||||||
@@ -2433,9 +2399,7 @@ fn deserialize_identifier(
|
|||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
match __value {
|
match __value {
|
||||||
#(
|
#(#bytes_mapping,)*
|
||||||
#field_bytes => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
_ => {
|
||||||
#bytes_to_str
|
#bytes_to_str
|
||||||
#value_as_borrowed_bytes_content
|
#value_as_borrowed_bytes_content
|
||||||
@@ -2460,9 +2424,7 @@ fn deserialize_identifier(
|
|||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
match __value {
|
match __value {
|
||||||
#(
|
#(#str_mapping,)*
|
||||||
#field_strs => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
_ => {
|
||||||
#value_as_str_content
|
#value_as_str_content
|
||||||
#fallthrough_arm
|
#fallthrough_arm
|
||||||
@@ -2475,9 +2437,7 @@ fn deserialize_identifier(
|
|||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
match __value {
|
match __value {
|
||||||
#(
|
#(#bytes_mapping,)*
|
||||||
#field_bytes => _serde::__private::Ok(#constructors),
|
|
||||||
)*
|
|
||||||
_ => {
|
_ => {
|
||||||
#bytes_to_str
|
#bytes_to_str
|
||||||
#value_as_bytes_content
|
#value_as_bytes_content
|
||||||
@@ -2707,42 +2667,6 @@ fn deserialize_map(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
|
||||||
fn deserialize_struct_as_struct_in_place_visitor(
|
|
||||||
params: &Parameters,
|
|
||||||
fields: &[Field],
|
|
||||||
cattrs: &attr::Container,
|
|
||||||
) -> (Fragment, Fragment, Fragment) {
|
|
||||||
assert!(!cattrs.has_flatten());
|
|
||||||
|
|
||||||
let field_names_idents: Vec<_> = fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.filter(|&(_, field)| !field.attrs.skip_deserializing())
|
|
||||||
.map(|(i, field)| {
|
|
||||||
(
|
|
||||||
field.attrs.name().deserialize_name(),
|
|
||||||
field_i(i),
|
|
||||||
field.attrs.aliases(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fields_stmt = {
|
|
||||||
let field_names = field_names_idents.iter().map(|(name, _, _)| name);
|
|
||||||
quote_block! {
|
|
||||||
#[doc(hidden)]
|
|
||||||
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
|
|
||||||
|
|
||||||
let visit_map = deserialize_map_in_place(params, fields, cattrs);
|
|
||||||
|
|
||||||
(field_visitor, fields_stmt, visit_map)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "deserialize_in_place")]
|
#[cfg(feature = "deserialize_in_place")]
|
||||||
fn deserialize_map_in_place(
|
fn deserialize_map_in_place(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
@@ -3046,6 +2970,35 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expr_is_missing_seq(
|
||||||
|
assign_to: Option<TokenStream>,
|
||||||
|
index: usize,
|
||||||
|
field: &Field,
|
||||||
|
cattrs: &attr::Container,
|
||||||
|
expecting: &str,
|
||||||
|
) -> TokenStream {
|
||||||
|
match field.attrs.default() {
|
||||||
|
attr::Default::Default => {
|
||||||
|
let span = field.original.span();
|
||||||
|
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
|
||||||
|
}
|
||||||
|
attr::Default::Path(path) => {
|
||||||
|
return quote_spanned!(path.span()=> #assign_to #path());
|
||||||
|
}
|
||||||
|
attr::Default::None => { /* below */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
match *cattrs.default() {
|
||||||
|
attr::Default::Default | attr::Default::Path(_) => {
|
||||||
|
let member = &field.member;
|
||||||
|
quote!(#assign_to __default.#member)
|
||||||
|
}
|
||||||
|
attr::Default::None => quote!(
|
||||||
|
return _serde::__private::Err(_serde::de::Error::invalid_length(#index, &#expecting))
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn effective_style(variant: &Variant) -> Style {
|
fn effective_style(variant: &Variant) -> Style {
|
||||||
match variant.style {
|
match variant.style {
|
||||||
Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit,
|
Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit,
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ pub struct Name {
|
|||||||
serialize_renamed: bool,
|
serialize_renamed: bool,
|
||||||
deserialize: String,
|
deserialize: String,
|
||||||
deserialize_renamed: bool,
|
deserialize_renamed: bool,
|
||||||
deserialize_aliases: Vec<String>,
|
deserialize_aliases: BTreeSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unraw(ident: &Ident) -> String {
|
fn unraw(ident: &Ident) -> String {
|
||||||
@@ -148,16 +148,12 @@ impl Name {
|
|||||||
de_name: Attr<String>,
|
de_name: Attr<String>,
|
||||||
de_aliases: Option<VecAttr<String>>,
|
de_aliases: Option<VecAttr<String>>,
|
||||||
) -> Name {
|
) -> Name {
|
||||||
let deserialize_aliases = match de_aliases {
|
let mut alias_set = BTreeSet::new();
|
||||||
Some(de_aliases) => {
|
if let Some(de_aliases) = de_aliases {
|
||||||
let mut alias_list = BTreeSet::new();
|
for alias_name in de_aliases.get() {
|
||||||
for alias_name in de_aliases.get() {
|
alias_set.insert(alias_name);
|
||||||
alias_list.insert(alias_name);
|
|
||||||
}
|
|
||||||
alias_list.into_iter().collect()
|
|
||||||
}
|
}
|
||||||
None => Vec::new(),
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let ser_name = ser_name.get();
|
let ser_name = ser_name.get();
|
||||||
let ser_renamed = ser_name.is_some();
|
let ser_renamed = ser_name.is_some();
|
||||||
@@ -168,27 +164,22 @@ impl Name {
|
|||||||
serialize_renamed: ser_renamed,
|
serialize_renamed: ser_renamed,
|
||||||
deserialize: de_name.unwrap_or(source_name),
|
deserialize: de_name.unwrap_or(source_name),
|
||||||
deserialize_renamed: de_renamed,
|
deserialize_renamed: de_renamed,
|
||||||
deserialize_aliases,
|
deserialize_aliases: alias_set,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the container name for the container when serializing.
|
/// Return the container name for the container when serializing.
|
||||||
pub fn serialize_name(&self) -> String {
|
pub fn serialize_name(&self) -> &str {
|
||||||
self.serialize.clone()
|
&self.serialize
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the container name for the container when deserializing.
|
/// Return the container name for the container when deserializing.
|
||||||
pub fn deserialize_name(&self) -> String {
|
pub fn deserialize_name(&self) -> &str {
|
||||||
self.deserialize.clone()
|
&self.deserialize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_aliases(&self) -> Vec<String> {
|
fn deserialize_aliases(&self) -> &BTreeSet<String> {
|
||||||
let mut aliases = self.deserialize_aliases.clone();
|
&self.deserialize_aliases
|
||||||
let main_name = self.deserialize_name();
|
|
||||||
if !aliases.contains(&main_name) {
|
|
||||||
aliases.push(main_name);
|
|
||||||
}
|
|
||||||
aliases
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,20 +396,20 @@ impl Container {
|
|||||||
if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
|
if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
|
||||||
match &item.data {
|
match &item.data {
|
||||||
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
|
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
|
||||||
syn::Fields::Named(_) => {
|
syn::Fields::Named(_) | syn::Fields::Unnamed(_) => {
|
||||||
default.set(&meta.path, Default::Path(path));
|
default.set(&meta.path, Default::Path(path));
|
||||||
}
|
}
|
||||||
syn::Fields::Unnamed(_) | syn::Fields::Unit => {
|
syn::Fields::Unit => {
|
||||||
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
|
let msg = "#[serde(default = \"...\")] can only be used on structs that have fields";
|
||||||
cx.syn_error(meta.error(msg));
|
cx.syn_error(meta.error(msg));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
syn::Data::Enum(_) => {
|
syn::Data::Enum(_) => {
|
||||||
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
|
let msg = "#[serde(default = \"...\")] can only be used on structs";
|
||||||
cx.syn_error(meta.error(msg));
|
cx.syn_error(meta.error(msg));
|
||||||
}
|
}
|
||||||
syn::Data::Union(_) => {
|
syn::Data::Union(_) => {
|
||||||
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
|
let msg = "#[serde(default = \"...\")] can only be used on structs";
|
||||||
cx.syn_error(meta.error(msg));
|
cx.syn_error(meta.error(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,20 +418,20 @@ impl Container {
|
|||||||
// #[serde(default)]
|
// #[serde(default)]
|
||||||
match &item.data {
|
match &item.data {
|
||||||
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
|
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
|
||||||
syn::Fields::Named(_) => {
|
syn::Fields::Named(_) | syn::Fields::Unnamed(_) => {
|
||||||
default.set(meta.path, Default::Default);
|
default.set(meta.path, Default::Default);
|
||||||
}
|
}
|
||||||
syn::Fields::Unnamed(_) | syn::Fields::Unit => {
|
syn::Fields::Unit => {
|
||||||
let msg = "#[serde(default)] can only be used on structs with named fields";
|
let msg = "#[serde(default)] can only be used on structs that have fields";
|
||||||
cx.error_spanned_by(fields, msg);
|
cx.error_spanned_by(fields, msg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
syn::Data::Enum(_) => {
|
syn::Data::Enum(_) => {
|
||||||
let msg = "#[serde(default)] can only be used on structs with named fields";
|
let msg = "#[serde(default)] can only be used on structs";
|
||||||
cx.syn_error(meta.error(msg));
|
cx.syn_error(meta.error(msg));
|
||||||
}
|
}
|
||||||
syn::Data::Union(_) => {
|
syn::Data::Union(_) => {
|
||||||
let msg = "#[serde(default)] can only be used on structs with named fields";
|
let msg = "#[serde(default)] can only be used on structs";
|
||||||
cx.syn_error(meta.error(msg));
|
cx.syn_error(meta.error(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -977,7 +968,7 @@ impl Variant {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aliases(&self) -> Vec<String> {
|
pub fn aliases(&self) -> &BTreeSet<String> {
|
||||||
self.name.deserialize_aliases()
|
self.name.deserialize_aliases()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,6 +979,9 @@ impl Variant {
|
|||||||
if !self.name.deserialize_renamed {
|
if !self.name.deserialize_renamed {
|
||||||
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
|
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
|
||||||
}
|
}
|
||||||
|
self.name
|
||||||
|
.deserialize_aliases
|
||||||
|
.insert(self.name.deserialize.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rename_all_rules(&self) -> RenameAllRules {
|
pub fn rename_all_rules(&self) -> RenameAllRules {
|
||||||
@@ -1316,7 +1310,7 @@ impl Field {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aliases(&self) -> Vec<String> {
|
pub fn aliases(&self) -> &BTreeSet<String> {
|
||||||
self.name.deserialize_aliases()
|
self.name.deserialize_aliases()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,6 +1321,9 @@ impl Field {
|
|||||||
if !self.name.deserialize_renamed {
|
if !self.name.deserialize_renamed {
|
||||||
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
|
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
|
||||||
}
|
}
|
||||||
|
self.name
|
||||||
|
.deserialize_aliases
|
||||||
|
.insert(self.name.deserialize.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn skip_serializing(&self) -> bool {
|
pub fn skip_serializing(&self) -> bool {
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use crate::internals::ast::{Container, Data, Field, Style};
|
use crate::internals::ast::{Container, Data, Field, Style};
|
||||||
use crate::internals::attr::{Identifier, TagType};
|
use crate::internals::attr::{Default, Identifier, TagType};
|
||||||
use crate::internals::{ungroup, Ctxt, Derive};
|
use crate::internals::{ungroup, Ctxt, Derive};
|
||||||
use syn::{Member, Type};
|
use syn::{Member, Type};
|
||||||
|
|
||||||
// Cross-cutting checks that require looking at more than a single attrs object.
|
// Cross-cutting checks that require looking at more than a single attrs object.
|
||||||
// Simpler checks should happen when parsing and building the attrs.
|
// Simpler checks should happen when parsing and building the attrs.
|
||||||
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||||
|
check_default_on_tuple(cx, cont);
|
||||||
check_remote_generic(cx, cont);
|
check_remote_generic(cx, cont);
|
||||||
check_getter(cx, cont);
|
check_getter(cx, cont);
|
||||||
check_flatten(cx, cont);
|
check_flatten(cx, cont);
|
||||||
@@ -17,6 +18,39 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
|||||||
check_from_and_try_from(cx, cont);
|
check_from_and_try_from(cx, cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If some field of a tuple struct is marked #[serde(default)] then all fields
|
||||||
|
// after it must also be marked with that attribute, or the struct must have a
|
||||||
|
// container-level serde(default) attribute. A field's default value is only
|
||||||
|
// used for tuple fields if the sequence is exhausted at that point; that means
|
||||||
|
// all subsequent fields will fail to deserialize if they don't have their own
|
||||||
|
// default.
|
||||||
|
fn check_default_on_tuple(cx: &Ctxt, cont: &Container) {
|
||||||
|
if let Default::None = cont.attrs.default() {
|
||||||
|
if let Data::Struct(Style::Tuple, fields) = &cont.data {
|
||||||
|
let mut first_default_index = None;
|
||||||
|
for (i, field) in fields.iter().enumerate() {
|
||||||
|
// Skipped fields automatically get the #[serde(default)]
|
||||||
|
// attribute. We are interested only on non-skipped fields here.
|
||||||
|
if field.attrs.skip_deserializing() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Default::None = field.attrs.default() {
|
||||||
|
if let Some(first) = first_default_index {
|
||||||
|
cx.error_spanned_by(
|
||||||
|
field.ty,
|
||||||
|
format!("field must have #[serde(default)] because previous field {} has #[serde(default)]", first),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if first_default_index.is_none() {
|
||||||
|
first_default_index = Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remote derive definition type must have either all of the generics of the
|
// Remote derive definition type must have either all of the generics of the
|
||||||
// remote type:
|
// remote type:
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
//!
|
//!
|
||||||
//! [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.178")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.183")]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
#![allow(
|
#![allow(
|
||||||
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
|
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
|
||||||
|
|||||||
+28
-13
@@ -478,7 +478,14 @@ fn serialize_variant(
|
|||||||
serialize_internally_tagged_variant(params, variant, cattrs, tag)
|
serialize_internally_tagged_variant(params, variant, cattrs, tag)
|
||||||
}
|
}
|
||||||
(attr::TagType::Adjacent { tag, content }, false) => {
|
(attr::TagType::Adjacent { tag, content }, false) => {
|
||||||
serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content)
|
serialize_adjacently_tagged_variant(
|
||||||
|
params,
|
||||||
|
variant,
|
||||||
|
cattrs,
|
||||||
|
variant_index,
|
||||||
|
tag,
|
||||||
|
content,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
(attr::TagType::None, _) | (_, true) => {
|
(attr::TagType::None, _) | (_, true) => {
|
||||||
serialize_untagged_variant(params, variant, cattrs)
|
serialize_untagged_variant(params, variant, cattrs)
|
||||||
@@ -559,7 +566,7 @@ fn serialize_externally_tagged_variant(
|
|||||||
},
|
},
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&type_name,
|
type_name,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -624,7 +631,7 @@ fn serialize_internally_tagged_variant(
|
|||||||
StructVariant::InternallyTagged { tag, variant_name },
|
StructVariant::InternallyTagged { tag, variant_name },
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&type_name,
|
type_name,
|
||||||
),
|
),
|
||||||
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
Style::Tuple => unreachable!("checked in serde_derive_internals"),
|
||||||
}
|
}
|
||||||
@@ -634,12 +641,20 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
variant: &Variant,
|
variant: &Variant,
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
|
variant_index: u32,
|
||||||
tag: &str,
|
tag: &str,
|
||||||
content: &str,
|
content: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this_type = ¶ms.this_type;
|
let this_type = ¶ms.this_type;
|
||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
let variant_name = variant.attrs.name().serialize_name();
|
let variant_name = variant.attrs.name().serialize_name();
|
||||||
|
let serialize_variant = quote! {
|
||||||
|
&_serde::__private::ser::AdjacentlyTaggedEnumVariant {
|
||||||
|
enum_name: #type_name,
|
||||||
|
variant_index: #variant_index,
|
||||||
|
variant_name: #variant_name,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
|
let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
|
||||||
let ser = wrap_serialize_variant_with(params, path, variant);
|
let ser = wrap_serialize_variant_with(params, path, variant);
|
||||||
@@ -653,7 +668,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
let mut __struct = _serde::Serializer::serialize_struct(
|
let mut __struct = _serde::Serializer::serialize_struct(
|
||||||
__serializer, #type_name, 1)?;
|
__serializer, #type_name, 1)?;
|
||||||
_serde::ser::SerializeStruct::serialize_field(
|
_serde::ser::SerializeStruct::serialize_field(
|
||||||
&mut __struct, #tag, #variant_name)?;
|
&mut __struct, #tag, #serialize_variant)?;
|
||||||
_serde::ser::SerializeStruct::end(__struct)
|
_serde::ser::SerializeStruct::end(__struct)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -670,7 +685,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
let mut __struct = _serde::Serializer::serialize_struct(
|
let mut __struct = _serde::Serializer::serialize_struct(
|
||||||
__serializer, #type_name, 2)?;
|
__serializer, #type_name, 2)?;
|
||||||
_serde::ser::SerializeStruct::serialize_field(
|
_serde::ser::SerializeStruct::serialize_field(
|
||||||
&mut __struct, #tag, #variant_name)?;
|
&mut __struct, #tag, #serialize_variant)?;
|
||||||
#func(
|
#func(
|
||||||
&mut __struct, #content, #field_expr)?;
|
&mut __struct, #content, #field_expr)?;
|
||||||
_serde::ser::SerializeStruct::end(__struct)
|
_serde::ser::SerializeStruct::end(__struct)
|
||||||
@@ -683,7 +698,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
StructVariant::Untagged,
|
StructVariant::Untagged,
|
||||||
params,
|
params,
|
||||||
&variant.fields,
|
&variant.fields,
|
||||||
&variant_name,
|
variant_name,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -735,7 +750,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
let mut __struct = _serde::Serializer::serialize_struct(
|
let mut __struct = _serde::Serializer::serialize_struct(
|
||||||
__serializer, #type_name, 2)?;
|
__serializer, #type_name, 2)?;
|
||||||
_serde::ser::SerializeStruct::serialize_field(
|
_serde::ser::SerializeStruct::serialize_field(
|
||||||
&mut __struct, #tag, #variant_name)?;
|
&mut __struct, #tag, #serialize_variant)?;
|
||||||
_serde::ser::SerializeStruct::serialize_field(
|
_serde::ser::SerializeStruct::serialize_field(
|
||||||
&mut __struct, #content, &__AdjacentlyTagged {
|
&mut __struct, #content, &__AdjacentlyTagged {
|
||||||
data: (#(#fields_ident,)*),
|
data: (#(#fields_ident,)*),
|
||||||
@@ -779,16 +794,16 @@ fn serialize_untagged_variant(
|
|||||||
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
|
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
|
||||||
Style::Struct => {
|
Style::Struct => {
|
||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name)
|
serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, type_name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TupleVariant {
|
enum TupleVariant<'a> {
|
||||||
ExternallyTagged {
|
ExternallyTagged {
|
||||||
type_name: String,
|
type_name: &'a str,
|
||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
variant_name: String,
|
variant_name: &'a str,
|
||||||
},
|
},
|
||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
@@ -855,11 +870,11 @@ fn serialize_tuple_variant(
|
|||||||
enum StructVariant<'a> {
|
enum StructVariant<'a> {
|
||||||
ExternallyTagged {
|
ExternallyTagged {
|
||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
variant_name: String,
|
variant_name: &'a str,
|
||||||
},
|
},
|
||||||
InternallyTagged {
|
InternallyTagged {
|
||||||
tag: &'a str,
|
tag: &'a str,
|
||||||
variant_name: String,
|
variant_name: &'a str,
|
||||||
},
|
},
|
||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ path = "lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] }
|
syn = { version = "2.0.28", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![allow(internal_features)]
|
||||||
#![feature(lang_items, start)]
|
#![feature(lang_items, start)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -114,42 +114,6 @@ struct CollectOther {
|
|||||||
extra: HashMap<String, u32>,
|
extra: HashMap<String, u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
struct FlattenStructEnumWrapper {
|
|
||||||
#[serde(flatten)]
|
|
||||||
data: FlattenStructEnum,
|
|
||||||
#[serde(flatten)]
|
|
||||||
extra: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
enum FlattenStructEnum {
|
|
||||||
InsertInteger { index: u32, value: u32 },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
struct FlattenStructTagContentEnumWrapper {
|
|
||||||
outer: u32,
|
|
||||||
#[serde(flatten)]
|
|
||||||
data: FlattenStructTagContentEnumNewtype,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum);
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
|
|
||||||
enum FlattenStructTagContentEnum {
|
|
||||||
InsertInteger { index: u32, value: u32 },
|
|
||||||
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
struct FlattenStructTagContentEnumNewtypeVariant {
|
|
||||||
value: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_default_struct() {
|
fn test_default_struct() {
|
||||||
assert_de_tokens(
|
assert_de_tokens(
|
||||||
@@ -641,7 +605,7 @@ fn test_unknown_field_rename_struct() {
|
|||||||
Token::Str("a4"),
|
Token::Str("a4"),
|
||||||
Token::I32(3),
|
Token::I32(3),
|
||||||
],
|
],
|
||||||
"unknown field `a4`, expected one of `a1`, `a3`, `a2`, `a5`, `a6`",
|
"unknown field `a4`, expected one of `a1`, `a2`, `a3`, `a5`, `a6`",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,7 +799,7 @@ fn test_unknown_field_rename_enum() {
|
|||||||
Token::Str("d"),
|
Token::Str("d"),
|
||||||
Token::I8(2),
|
Token::I8(2),
|
||||||
],
|
],
|
||||||
"unknown field `d`, expected one of `a`, `c`, `b`, `e`, `f`",
|
"unknown field `d`, expected one of `a`, `b`, `c`, `e`, `f`",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1643,149 +1607,6 @@ fn test_collect_other() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_flatten_struct_enum() {
|
|
||||||
let mut extra = HashMap::new();
|
|
||||||
extra.insert("extra_key".into(), "extra value".into());
|
|
||||||
let change_request = FlattenStructEnumWrapper {
|
|
||||||
data: FlattenStructEnum::InsertInteger {
|
|
||||||
index: 0,
|
|
||||||
value: 42,
|
|
||||||
},
|
|
||||||
extra,
|
|
||||||
};
|
|
||||||
assert_de_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("insert_integer"),
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("index"),
|
|
||||||
Token::U32(0),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::MapEnd,
|
|
||||||
Token::Str("extra_key"),
|
|
||||||
Token::Str("extra value"),
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
assert_ser_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("insert_integer"),
|
|
||||||
Token::Struct {
|
|
||||||
len: 2,
|
|
||||||
name: "insert_integer",
|
|
||||||
},
|
|
||||||
Token::Str("index"),
|
|
||||||
Token::U32(0),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::StructEnd,
|
|
||||||
Token::Str("extra_key"),
|
|
||||||
Token::Str("extra value"),
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_flatten_struct_tag_content_enum() {
|
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
|
||||||
outer: 42,
|
|
||||||
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger {
|
|
||||||
index: 0,
|
|
||||||
value: 42,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
assert_de_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("outer"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::Str("type"),
|
|
||||||
Token::Str("insert_integer"),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("index"),
|
|
||||||
Token::U32(0),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::MapEnd,
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
assert_ser_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("outer"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::Str("type"),
|
|
||||||
Token::Str("insert_integer"),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::Struct {
|
|
||||||
len: 2,
|
|
||||||
name: "insert_integer",
|
|
||||||
},
|
|
||||||
Token::Str("index"),
|
|
||||||
Token::U32(0),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::StructEnd,
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_flatten_struct_tag_content_enum_newtype() {
|
|
||||||
let change_request = FlattenStructTagContentEnumWrapper {
|
|
||||||
outer: 42,
|
|
||||||
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant(
|
|
||||||
FlattenStructTagContentEnumNewtypeVariant { value: 23 },
|
|
||||||
)),
|
|
||||||
};
|
|
||||||
assert_de_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("outer"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::Str("type"),
|
|
||||||
Token::Str("newtype_variant"),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(23),
|
|
||||||
Token::MapEnd,
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
assert_ser_tokens(
|
|
||||||
&change_request,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("outer"),
|
|
||||||
Token::U32(42),
|
|
||||||
Token::Str("type"),
|
|
||||||
Token::Str("newtype_variant"),
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::Struct {
|
|
||||||
len: 1,
|
|
||||||
name: "FlattenStructTagContentEnumNewtypeVariant",
|
|
||||||
},
|
|
||||||
Token::Str("value"),
|
|
||||||
Token::U32(23),
|
|
||||||
Token::StructEnd,
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unknown_field_in_flatten() {
|
fn test_unknown_field_in_flatten() {
|
||||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -2142,86 +1963,6 @@ fn test_lifetime_propagation_for_flatten() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_flatten_enum_newtype() {
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
||||||
struct S {
|
|
||||||
#[serde(flatten)]
|
|
||||||
flat: E,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
|
||||||
enum E {
|
|
||||||
Q(HashMap<String, String>),
|
|
||||||
}
|
|
||||||
|
|
||||||
let e = E::Q({
|
|
||||||
let mut map = HashMap::new();
|
|
||||||
map.insert("k".to_owned(), "v".to_owned());
|
|
||||||
map
|
|
||||||
});
|
|
||||||
let s = S { flat: e };
|
|
||||||
|
|
||||||
assert_tokens(
|
|
||||||
&s,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("Q"),
|
|
||||||
Token::Map { len: Some(1) },
|
|
||||||
Token::Str("k"),
|
|
||||||
Token::Str("v"),
|
|
||||||
Token::MapEnd,
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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]
|
#[test]
|
||||||
fn test_externally_tagged_enum_containing_flatten() {
|
fn test_externally_tagged_enum_containing_flatten() {
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
@@ -2367,7 +2108,10 @@ fn test_adjacently_tagged_enum_bytes() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("A"),
|
Token::UnitVariant {
|
||||||
|
name: "Data",
|
||||||
|
variant: "A",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Struct { name: "A", len: 1 },
|
Token::Struct { name: "A", len: 1 },
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
@@ -2385,7 +2129,10 @@ fn test_adjacently_tagged_enum_bytes() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Bytes(b"t"),
|
Token::Bytes(b"t"),
|
||||||
Token::Str("A"),
|
Token::UnitVariant {
|
||||||
|
name: "Data",
|
||||||
|
variant: "A",
|
||||||
|
},
|
||||||
Token::Bytes(b"c"),
|
Token::Bytes(b"c"),
|
||||||
Token::Struct { name: "A", len: 1 },
|
Token::Struct { name: "A", len: 1 },
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
@@ -2426,7 +2173,10 @@ fn test_adjacently_tagged_enum_containing_flatten() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("A"),
|
Token::UnitVariant {
|
||||||
|
name: "Data",
|
||||||
|
variant: "A",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Map { len: None },
|
Token::Map { len: None },
|
||||||
Token::Str("a"),
|
Token::Str("a"),
|
||||||
@@ -2630,35 +2380,6 @@ fn test_partially_untagged_enum_desugared() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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]
|
#[test]
|
||||||
fn test_flatten_option() {
|
fn test_flatten_option() {
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
@@ -2815,48 +2536,6 @@ fn test_internally_tagged_unit_enum_with_unknown_fields() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() {
|
|
||||||
#[derive(Deserialize, PartialEq, Debug)]
|
|
||||||
struct S {
|
|
||||||
#[serde(flatten)]
|
|
||||||
x: X,
|
|
||||||
#[serde(flatten)]
|
|
||||||
y: Y,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, PartialEq, Debug)]
|
|
||||||
#[serde(tag = "typeX")]
|
|
||||||
enum X {
|
|
||||||
A,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, PartialEq, Debug)]
|
|
||||||
#[serde(tag = "typeY")]
|
|
||||||
enum Y {
|
|
||||||
B { c: u32 },
|
|
||||||
}
|
|
||||||
|
|
||||||
let s = S {
|
|
||||||
x: X::A,
|
|
||||||
y: Y::B { c: 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_de_tokens(
|
|
||||||
&s,
|
|
||||||
&[
|
|
||||||
Token::Map { len: None },
|
|
||||||
Token::Str("typeX"),
|
|
||||||
Token::Str("A"),
|
|
||||||
Token::Str("typeY"),
|
|
||||||
Token::Str("B"),
|
|
||||||
Token::Str("c"),
|
|
||||||
Token::I32(0),
|
|
||||||
Token::MapEnd,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_flatten_any_after_flatten_struct() {
|
fn test_flatten_any_after_flatten_struct() {
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
@@ -3087,7 +2766,7 @@ fn test_expecting_message_adjacently_tagged_enum() {
|
|||||||
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
|
||||||
assert_de_tokens_error::<Enum>(
|
assert_de_tokens_error::<Enum>(
|
||||||
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
|
||||||
r#"invalid type: unit value, expected variant identifier"#,
|
r#"invalid type: unit value, expected variant of enum Enum"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3149,3 +2828,345 @@ fn test_expecting_message_identifier_enum() {
|
|||||||
r#"invalid type: map, expected something strange..."#,
|
r#"invalid type: map, expected something strange..."#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod flatten {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod enum_ {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
mod externally_tagged {
|
||||||
|
use super::*;
|
||||||
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
data: Enum,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
extra: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
enum Enum {
|
||||||
|
Newtype(HashMap<String, String>),
|
||||||
|
Tuple(u32, u32),
|
||||||
|
Struct { index: u32, value: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn newtype() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])),
|
||||||
|
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("Newtype"), // variant
|
||||||
|
Token::Map { len: Some(1) },
|
||||||
|
Token::Str("key"),
|
||||||
|
Token::Str("value"),
|
||||||
|
Token::MapEnd,
|
||||||
|
Token::Str("extra_key"),
|
||||||
|
Token::Str("extra value"),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::tuple_variant
|
||||||
|
// Content::Seq case
|
||||||
|
// via FlatMapDeserializer::deserialize_enum
|
||||||
|
#[test]
|
||||||
|
fn tuple() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
data: Enum::Tuple(0, 42),
|
||||||
|
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("Tuple"), // variant
|
||||||
|
Token::Seq { len: Some(2) },
|
||||||
|
Token::U32(0),
|
||||||
|
Token::U32(42),
|
||||||
|
Token::SeqEnd,
|
||||||
|
Token::Str("extra_key"),
|
||||||
|
Token::Str("extra value"),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
|
||||||
|
// Content::Seq case
|
||||||
|
// via FlatMapDeserializer::deserialize_enum
|
||||||
|
#[test]
|
||||||
|
fn struct_from_seq() {
|
||||||
|
assert_de_tokens(
|
||||||
|
&Flatten {
|
||||||
|
data: Enum::Struct {
|
||||||
|
index: 0,
|
||||||
|
value: 42,
|
||||||
|
},
|
||||||
|
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("Struct"), // variant
|
||||||
|
Token::Seq { len: Some(2) },
|
||||||
|
Token::U32(0), // index
|
||||||
|
Token::U32(42), // value
|
||||||
|
Token::SeqEnd,
|
||||||
|
Token::Str("extra_key"),
|
||||||
|
Token::Str("extra value"),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
|
||||||
|
// Content::Map case
|
||||||
|
// via FlatMapDeserializer::deserialize_enum
|
||||||
|
#[test]
|
||||||
|
fn struct_from_map() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
data: Enum::Struct {
|
||||||
|
index: 0,
|
||||||
|
value: 42,
|
||||||
|
},
|
||||||
|
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("Struct"), // variant
|
||||||
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "Struct",
|
||||||
|
},
|
||||||
|
Token::Str("index"),
|
||||||
|
Token::U32(0),
|
||||||
|
Token::Str("value"),
|
||||||
|
Token::U32(42),
|
||||||
|
Token::StructEnd,
|
||||||
|
Token::Str("extra_key"),
|
||||||
|
Token::Str("extra value"),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod adjacently_tagged {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct Flatten {
|
||||||
|
outer: u32,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
data: NewtypeWrapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct NewtypeWrapper(pub Enum);
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "tag", content = "content")]
|
||||||
|
enum Enum {
|
||||||
|
Newtype(NewtypeVariant),
|
||||||
|
Struct { index: u32, value: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct NewtypeVariant {
|
||||||
|
value: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn struct_() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
outer: 42,
|
||||||
|
data: NewtypeWrapper(Enum::Struct {
|
||||||
|
index: 0,
|
||||||
|
value: 42,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("outer"),
|
||||||
|
Token::U32(42),
|
||||||
|
Token::Str("tag"),
|
||||||
|
Token::UnitVariant {
|
||||||
|
name: "Enum",
|
||||||
|
variant: "Struct",
|
||||||
|
},
|
||||||
|
Token::Str("content"),
|
||||||
|
Token::Struct {
|
||||||
|
len: 2,
|
||||||
|
name: "Struct",
|
||||||
|
},
|
||||||
|
Token::Str("index"),
|
||||||
|
Token::U32(0),
|
||||||
|
Token::Str("value"),
|
||||||
|
Token::U32(42),
|
||||||
|
Token::StructEnd,
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn newtype() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
outer: 42,
|
||||||
|
data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })),
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("outer"),
|
||||||
|
Token::U32(42),
|
||||||
|
Token::Str("tag"),
|
||||||
|
Token::UnitVariant {
|
||||||
|
name: "Enum",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
|
Token::Str("content"),
|
||||||
|
Token::Struct {
|
||||||
|
len: 1,
|
||||||
|
name: "NewtypeVariant",
|
||||||
|
},
|
||||||
|
Token::Str("value"),
|
||||||
|
Token::U32(23),
|
||||||
|
Token::StructEnd,
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod internally_tagged {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn structs() {
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
x: X,
|
||||||
|
#[serde(flatten)]
|
||||||
|
y: Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "typeX")]
|
||||||
|
enum X {
|
||||||
|
A { a: i32 },
|
||||||
|
B { b: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "typeY")]
|
||||||
|
enum Y {
|
||||||
|
C { c: i32 },
|
||||||
|
D { d: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
x: X::B { b: 1 },
|
||||||
|
y: Y::D { d: 2 },
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
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 unit_enum_with_unknown_fields() {
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
struct Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
x: X,
|
||||||
|
#[serde(flatten)]
|
||||||
|
y: Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
#[serde(tag = "typeX")]
|
||||||
|
enum X {
|
||||||
|
A,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
#[serde(tag = "typeY")]
|
||||||
|
enum Y {
|
||||||
|
B { c: u32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(
|
||||||
|
&Flatten {
|
||||||
|
x: X::A,
|
||||||
|
y: Y::B { c: 0 },
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("typeX"),
|
||||||
|
Token::Str("A"),
|
||||||
|
Token::Str("typeY"),
|
||||||
|
Token::Str("B"),
|
||||||
|
Token::Str("c"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod untagged {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
struct Flatten {
|
||||||
|
#[serde(flatten)]
|
||||||
|
data: Enum,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum Enum {
|
||||||
|
Struct { a: i32 },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn struct_() {
|
||||||
|
assert_tokens(
|
||||||
|
&Flatten {
|
||||||
|
data: Enum::Struct { a: 0 },
|
||||||
|
},
|
||||||
|
&[
|
||||||
|
Token::Map { len: None },
|
||||||
|
Token::Str("a"),
|
||||||
|
Token::I32(0),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,86 +3,186 @@
|
|||||||
#![allow(clippy::derive_partial_eq_without_eq)]
|
#![allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use serde_test::{assert_de_tokens, Token};
|
use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
|
||||||
|
|
||||||
|
mod variant_identifier {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_variant_identifier() {
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
#[serde(variant_identifier)]
|
#[serde(variant_identifier)]
|
||||||
enum V {
|
enum V {
|
||||||
Aaa,
|
Aaa,
|
||||||
|
#[serde(alias = "Ccc", alias = "Ddd")]
|
||||||
Bbb,
|
Bbb,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(&V::Aaa, &[Token::U8(0)]);
|
#[test]
|
||||||
assert_de_tokens(&V::Aaa, &[Token::U16(0)]);
|
fn variant1() {
|
||||||
assert_de_tokens(&V::Aaa, &[Token::U32(0)]);
|
assert_de_tokens(&V::Aaa, &[Token::U8(0)]);
|
||||||
assert_de_tokens(&V::Aaa, &[Token::U64(0)]);
|
assert_de_tokens(&V::Aaa, &[Token::U16(0)]);
|
||||||
assert_de_tokens(&V::Aaa, &[Token::Str("Aaa")]);
|
assert_de_tokens(&V::Aaa, &[Token::U32(0)]);
|
||||||
assert_de_tokens(&V::Aaa, &[Token::Bytes(b"Aaa")]);
|
assert_de_tokens(&V::Aaa, &[Token::U64(0)]);
|
||||||
|
assert_de_tokens(&V::Aaa, &[Token::Str("Aaa")]);
|
||||||
|
assert_de_tokens(&V::Aaa, &[Token::Bytes(b"Aaa")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn aliases() {
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::U8(1)]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::U16(1)]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::U32(1)]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::U64(1)]);
|
||||||
|
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Str("Bbb")]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Bbb")]);
|
||||||
|
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Str("Ccc")]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Ccc")]);
|
||||||
|
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Str("Ddd")]);
|
||||||
|
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Ddd")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unknown() {
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::U8(42)],
|
||||||
|
"invalid value: integer `42`, expected variant index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::U16(42)],
|
||||||
|
"invalid value: integer `42`, expected variant index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::U32(42)],
|
||||||
|
"invalid value: integer `42`, expected variant index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::U64(42)],
|
||||||
|
"invalid value: integer `42`, expected variant index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::Str("Unknown")],
|
||||||
|
"unknown variant `Unknown`, expected one of `Aaa`, `Bbb`, `Ccc`, `Ddd`",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<V>(
|
||||||
|
&[Token::Bytes(b"Unknown")],
|
||||||
|
"unknown variant `Unknown`, expected one of `Aaa`, `Bbb`, `Ccc`, `Ddd`",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
mod field_identifier {
|
||||||
fn test_field_identifier() {
|
use super::*;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
#[serde(field_identifier, rename_all = "snake_case")]
|
#[serde(field_identifier, rename_all = "snake_case")]
|
||||||
enum F {
|
enum F {
|
||||||
Aaa,
|
Aaa,
|
||||||
|
#[serde(alias = "ccc", alias = "ddd")]
|
||||||
Bbb,
|
Bbb,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(&F::Aaa, &[Token::U8(0)]);
|
#[test]
|
||||||
assert_de_tokens(&F::Aaa, &[Token::U16(0)]);
|
fn field1() {
|
||||||
assert_de_tokens(&F::Aaa, &[Token::U32(0)]);
|
assert_de_tokens(&F::Aaa, &[Token::U8(0)]);
|
||||||
assert_de_tokens(&F::Aaa, &[Token::U64(0)]);
|
assert_de_tokens(&F::Aaa, &[Token::U16(0)]);
|
||||||
assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]);
|
assert_de_tokens(&F::Aaa, &[Token::U32(0)]);
|
||||||
assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]);
|
assert_de_tokens(&F::Aaa, &[Token::U64(0)]);
|
||||||
}
|
assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]);
|
||||||
|
assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]);
|
||||||
#[test]
|
|
||||||
fn test_unit_fallthrough() {
|
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
|
||||||
#[serde(field_identifier, rename_all = "snake_case")]
|
|
||||||
enum F {
|
|
||||||
Aaa,
|
|
||||||
Bbb,
|
|
||||||
#[serde(other)]
|
|
||||||
Other,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(&F::Other, &[Token::U8(42)]);
|
#[test]
|
||||||
assert_de_tokens(&F::Other, &[Token::U16(42)]);
|
fn aliases() {
|
||||||
assert_de_tokens(&F::Other, &[Token::U32(42)]);
|
assert_de_tokens(&F::Bbb, &[Token::U8(1)]);
|
||||||
assert_de_tokens(&F::Other, &[Token::U64(42)]);
|
assert_de_tokens(&F::Bbb, &[Token::U16(1)]);
|
||||||
assert_de_tokens(&F::Other, &[Token::Str("x")]);
|
assert_de_tokens(&F::Bbb, &[Token::U32(1)]);
|
||||||
}
|
assert_de_tokens(&F::Bbb, &[Token::U64(1)]);
|
||||||
|
|
||||||
#[test]
|
assert_de_tokens(&F::Bbb, &[Token::Str("bbb")]);
|
||||||
fn test_newtype_fallthrough() {
|
assert_de_tokens(&F::Bbb, &[Token::Bytes(b"bbb")]);
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
|
||||||
#[serde(field_identifier, rename_all = "snake_case")]
|
assert_de_tokens(&F::Bbb, &[Token::Str("ccc")]);
|
||||||
enum F {
|
assert_de_tokens(&F::Bbb, &[Token::Bytes(b"ccc")]);
|
||||||
Aaa,
|
|
||||||
Bbb,
|
assert_de_tokens(&F::Bbb, &[Token::Str("ddd")]);
|
||||||
Other(String),
|
assert_de_tokens(&F::Bbb, &[Token::Bytes(b"ddd")]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
|
#[test]
|
||||||
}
|
fn unknown() {
|
||||||
|
assert_de_tokens_error::<F>(
|
||||||
#[test]
|
&[Token::U8(42)],
|
||||||
fn test_newtype_fallthrough_generic() {
|
"invalid value: integer `42`, expected field index 0 <= i < 2",
|
||||||
#[derive(Deserialize, Debug, PartialEq)]
|
);
|
||||||
#[serde(field_identifier, rename_all = "snake_case")]
|
assert_de_tokens_error::<F>(
|
||||||
enum F<T> {
|
&[Token::U16(42)],
|
||||||
Aaa,
|
"invalid value: integer `42`, expected field index 0 <= i < 2",
|
||||||
Bbb,
|
);
|
||||||
Other(T),
|
assert_de_tokens_error::<F>(
|
||||||
|
&[Token::U32(42)],
|
||||||
|
"invalid value: integer `42`, expected field index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<F>(
|
||||||
|
&[Token::U64(42)],
|
||||||
|
"invalid value: integer `42`, expected field index 0 <= i < 2",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<F>(
|
||||||
|
&[Token::Str("unknown")],
|
||||||
|
"unknown field `unknown`, expected one of `aaa`, `bbb`, `ccc`, `ddd`",
|
||||||
|
);
|
||||||
|
assert_de_tokens_error::<F>(
|
||||||
|
&[Token::Bytes(b"unknown")],
|
||||||
|
"unknown field `unknown`, expected one of `aaa`, `bbb`, `ccc`, `ddd`",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_de_tokens(&F::Other(42u8), &[Token::U8(42)]);
|
#[test]
|
||||||
assert_de_tokens(&F::Other(42u16), &[Token::U16(42)]);
|
fn unit_fallthrough() {
|
||||||
assert_de_tokens(&F::Other(42u32), &[Token::U32(42)]);
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
assert_de_tokens(&F::Other(42u64), &[Token::U64(42)]);
|
#[serde(field_identifier, rename_all = "snake_case")]
|
||||||
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
|
enum F {
|
||||||
|
Aaa,
|
||||||
|
Bbb,
|
||||||
|
#[serde(other)]
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(&F::Other, &[Token::U8(42)]);
|
||||||
|
assert_de_tokens(&F::Other, &[Token::U16(42)]);
|
||||||
|
assert_de_tokens(&F::Other, &[Token::U32(42)]);
|
||||||
|
assert_de_tokens(&F::Other, &[Token::U64(42)]);
|
||||||
|
assert_de_tokens(&F::Other, &[Token::Str("x")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn newtype_fallthrough() {
|
||||||
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
|
#[serde(field_identifier, rename_all = "snake_case")]
|
||||||
|
enum F {
|
||||||
|
Aaa,
|
||||||
|
Bbb,
|
||||||
|
Other(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn newtype_fallthrough_generic() {
|
||||||
|
#[derive(Deserialize, Debug, PartialEq)]
|
||||||
|
#[serde(field_identifier, rename_all = "snake_case")]
|
||||||
|
enum F<T> {
|
||||||
|
Aaa,
|
||||||
|
Bbb,
|
||||||
|
Other(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_de_tokens(&F::Other(42u8), &[Token::U8(42)]);
|
||||||
|
assert_de_tokens(&F::Other(42u16), &[Token::U16(42)]);
|
||||||
|
assert_de_tokens(&F::Other(42u32), &[Token::U32(42)]);
|
||||||
|
assert_de_tokens(&F::Other(42u64), &[Token::U64(42)]);
|
||||||
|
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -472,7 +472,10 @@ fn test_adjacently_tagged_newtype_struct() {
|
|||||||
},
|
},
|
||||||
Token::U32(5),
|
Token::U32(5),
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "E",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1066,7 +1069,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1080,7 +1086,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1094,7 +1103,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
@@ -1112,7 +1124,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1128,7 +1143,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::Str("f"),
|
Token::Str("f"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::Str("g"),
|
Token::Str("g"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
@@ -1148,7 +1166,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
@@ -1166,7 +1187,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1180,7 +1204,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 1,
|
len: 1,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1194,7 +1221,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Tuple"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Tuple",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Tuple { len: 2 },
|
Token::Tuple { len: 2 },
|
||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
@@ -1218,7 +1248,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::TupleEnd,
|
Token::TupleEnd,
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Tuple"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Tuple",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1232,7 +1265,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Struct"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Struct",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Struct {
|
Token::Struct {
|
||||||
name: "Struct",
|
name: "Struct",
|
||||||
@@ -1262,7 +1298,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Struct"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Struct",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1278,7 +1317,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::U64(1), // content field
|
Token::U64(1), // content field
|
||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::U64(0), // tag field
|
Token::U64(0), // tag field
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1294,7 +1336,10 @@ fn test_adjacently_tagged_enum() {
|
|||||||
Token::Bytes(b"c"),
|
Token::Bytes(b"c"),
|
||||||
Token::U8(1),
|
Token::U8(1),
|
||||||
Token::Bytes(b"t"),
|
Token::Bytes(b"t"),
|
||||||
Token::Str("Newtype"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Newtype",
|
||||||
|
},
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@@ -1316,7 +1361,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::StructEnd,
|
Token::StructEnd,
|
||||||
@@ -1330,7 +1378,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::Str("t"),
|
Token::Str("t"),
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::Str("c"),
|
Token::Str("c"),
|
||||||
Token::Unit,
|
Token::Unit,
|
||||||
Token::Str("h"),
|
Token::Str("h"),
|
||||||
@@ -1369,7 +1420,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
|
|||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Token::U64(0), // tag field
|
Token::U64(0), // tag field
|
||||||
Token::Str("Unit"),
|
Token::UnitVariant {
|
||||||
|
name: "AdjacentlyTagged",
|
||||||
|
variant: "Unit",
|
||||||
|
},
|
||||||
Token::U64(3),
|
Token::U64(3),
|
||||||
],
|
],
|
||||||
r#"invalid value: integer `3`, expected "t" or "c""#,
|
r#"invalid value: integer `3`, expected "t" or "c""#,
|
||||||
@@ -1429,6 +1483,9 @@ fn test_enum_in_internally_tagged_enum() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::tuple_variant
|
||||||
|
// Content::Seq case
|
||||||
|
// via ContentDeserializer::deserialize_enum
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&Outer::Inner(Inner::Tuple(1, 1)),
|
&Outer::Inner(Inner::Tuple(1, 1)),
|
||||||
&[
|
&[
|
||||||
@@ -1447,6 +1504,9 @@ fn test_enum_in_internally_tagged_enum() {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
|
||||||
|
// Content::Map case
|
||||||
|
// via ContentDeserializer::deserialize_enum
|
||||||
assert_tokens(
|
assert_tokens(
|
||||||
&Outer::Inner(Inner::Struct { f: 1 }),
|
&Outer::Inner(Inner::Struct { f: 1 }),
|
||||||
&[
|
&[
|
||||||
@@ -1464,6 +1524,23 @@ fn test_enum_in_internally_tagged_enum() {
|
|||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
|
||||||
|
// Content::Seq case
|
||||||
|
// via ContentDeserializer::deserialize_enum
|
||||||
|
assert_de_tokens(
|
||||||
|
&Outer::Inner(Inner::Struct { f: 1 }),
|
||||||
|
&[
|
||||||
|
Token::Map { len: Some(2) },
|
||||||
|
Token::Str("type"),
|
||||||
|
Token::Str("Inner"),
|
||||||
|
Token::Str("Struct"),
|
||||||
|
Token::Seq { len: Some(1) },
|
||||||
|
Token::U8(1), // f
|
||||||
|
Token::SeqEnd,
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1542,7 +1619,10 @@ fn test_internally_tagged_struct_with_flattened_field() {
|
|||||||
Token::Str("tag_struct"),
|
Token::Str("tag_struct"),
|
||||||
Token::Str("Struct"),
|
Token::Str("Struct"),
|
||||||
Token::Str("tag_enum"),
|
Token::Str("tag_enum"),
|
||||||
Token::Str("A"),
|
Token::UnitVariant {
|
||||||
|
name: "Enum",
|
||||||
|
variant: "A",
|
||||||
|
},
|
||||||
Token::Str("content"),
|
Token::Str("content"),
|
||||||
Token::U64(0),
|
Token::U64(0),
|
||||||
Token::MapEnd,
|
Token::MapEnd,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
error: #[serde(default)] can only be used on structs with named fields
|
error: #[serde(default)] can only be used on structs
|
||||||
--> tests/ui/default-attribute/enum.rs:4:9
|
--> tests/ui/default-attribute/enum.rs:4:9
|
||||||
|
|
|
|
||||||
4 | #[serde(default)]
|
4 | #[serde(default)]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
error: #[serde(default = "...")] can only be used on structs with named fields
|
error: #[serde(default = "...")] can only be used on structs
|
||||||
--> tests/ui/default-attribute/enum_path.rs:4:9
|
--> tests/ui/default-attribute/enum_path.rs:4:9
|
||||||
|
|
|
|
||||||
4 | #[serde(default = "default_e")]
|
4 | #[serde(default = "default_e")]
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
use serde_derive::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(default)]
|
|
||||||
struct T(u8, u8);
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
error: #[serde(default)] can only be used on structs with named fields
|
|
||||||
--> tests/ui/default-attribute/nameless_struct_fields.rs:5:9
|
|
||||||
|
|
|
||||||
5 | struct T(u8, u8);
|
|
||||||
| ^^^^^^^^
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
use serde_derive::Deserialize;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(default = "default_t")]
|
|
||||||
struct T(u8, u8);
|
|
||||||
|
|
||||||
fn main() {}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
error: #[serde(default = "...")] can only be used on structs with named fields
|
|
||||||
--> tests/ui/default-attribute/nameless_struct_fields_path.rs:4:9
|
|
||||||
|
|
|
||||||
4 | #[serde(default = "default_t")]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
|
// No errors expected.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T0(u8, u8);
|
||||||
|
|
||||||
|
// No errors expected:
|
||||||
|
// - If both fields are provided, both get value from data.
|
||||||
|
// - If only one field is provided, the second gets default value.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T1(u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
// ERROR: The first field can get default value only if sequence is empty, but
|
||||||
|
// that mean that all other fields cannot be deserialized without errors.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T2(#[serde(default)] u8, u8, u8);
|
||||||
|
|
||||||
|
// No errors expected:
|
||||||
|
// - If both fields are provided, both get value from data.
|
||||||
|
// - If only one field is provided, the second gets default value.
|
||||||
|
// - If no fields are provided, both get default value.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T3(#[serde(default)] u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T4(u8, u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T5(#[serde(default)] u8, u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T6(u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T7(#[serde(default)] u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
|
||||||
|
--> tests/ui/default-attribute/tuple_struct.rs:16:33
|
||||||
|
|
|
||||||
|
16 | struct T2(#[serde(default)] u8, u8, u8);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
|
||||||
|
--> tests/ui/default-attribute/tuple_struct.rs:16:37
|
||||||
|
|
|
||||||
|
16 | struct T2(#[serde(default)] u8, u8, u8);
|
||||||
|
| ^^
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
|
fn d<T>() -> T {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
// No errors expected:
|
||||||
|
// - If both fields are provided, both get value from data.
|
||||||
|
// - If only one field is provided, the second gets default value.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T1(u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
// ERROR: The first field can get default value only if sequence is empty, but
|
||||||
|
// that mean that all other fields cannot be deserialized without errors.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T2(#[serde(default = "d")] u8, u8, u8);
|
||||||
|
|
||||||
|
// No errors expected:
|
||||||
|
// - If both fields are provided, both get value from data.
|
||||||
|
// - If only one field is provided, the second gets default value.
|
||||||
|
// - If no fields are provided, both get default value.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct T3(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T1D(#[serde(default = "d")] u8, u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T2D(u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
struct T3D(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T1Path(#[serde(default)] u8, u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T2Path(u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T3Path(#[serde(default)] u8, #[serde(default)] u8);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T1PathD(#[serde(default = "d")] u8, u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T2PathD(u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
// No errors expected -- missing fields get default values.
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(default = "d")]
|
||||||
|
struct T3PathD(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
|
||||||
|
--> tests/ui/default-attribute/tuple_struct_path.rs:16:39
|
||||||
|
|
|
||||||
|
16 | struct T2(#[serde(default = "d")] u8, u8, u8);
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
|
||||||
|
--> tests/ui/default-attribute/tuple_struct_path.rs:16:43
|
||||||
|
|
|
||||||
|
16 | struct T2(#[serde(default = "d")] u8, u8, u8);
|
||||||
|
| ^^
|
||||||
Reference in New Issue
Block a user