mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 02:17:56 +00:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0353354d61 | |||
| 34ae0422f4 | |||
| cc128feb4c | |||
| 7766103174 | |||
| 30f7c7110d | |||
| 50354c2d0b | |||
| c4f67e679f | |||
| 0daafe423f | |||
| 37021910c9 | |||
| 7328b34810 | |||
| fabbd2b097 | |||
| 6814f978d7 | |||
| 4ea403c54a | |||
| f4f6b5af3a | |||
| 2062a3c16d | |||
| 9a53bd9125 | |||
| 4873b48b02 | |||
| e19844c659 | |||
| 93bb9e147c | |||
| ab230e6e44 | |||
| 51ea34b217 | |||
| 1050f6b808 | |||
| 15ec95a98d | |||
| 072145e0e9 | |||
| 92957f17f2 | |||
| 667db558b6 | |||
| f41509261e | |||
| 6d009711a2 | |||
| 354b48fd40 | |||
| 3fd8e52f0c | |||
| 142dce0d3d | |||
| 6aed101630 | |||
| e2ccfd9ea7 | |||
| a07d794f74 | |||
| 90d28fc314 | |||
| 55cf0ac51a | |||
| 07696c1674 | |||
| f803b290f3 | |||
| d96e181150 | |||
| 3ffb86fc70 | |||
| 649a72a587 | |||
| b2676348eb | |||
| 8c036ee5a3 | |||
| d99009f3c6 | |||
| be3c37eb8b | |||
| f0346ae054 | |||
| fa6ce42056 | |||
| a9320db6f9 | |||
| d208762c81 | |||
| 5386897d24 | |||
| 68eb59df0c | |||
| a7f4551669 | |||
| f52d134c14 | |||
| 6660676b0d | |||
| 1d42d3571a | |||
| ebd06eebdb | |||
| f1985823a3 | |||
| 60e4092b8e | |||
| 3d0251666e | |||
| 7770da4929 | |||
| a5fd85a9ef | |||
| abb2a8494d | |||
| a31d0be191 | |||
| d786e750d7 | |||
| 10e4839f83 | |||
| 85e72653c8 | |||
| c9cc8a8924 | |||
| a925ce4119 | |||
| c5f6338ce2 | |||
| 5185487d73 | |||
| efaafd4458 | |||
| a0eb83a5d4 | |||
| 7cc6f7fbb0 | |||
| 44b9496c91 | |||
| 7e1486d0da | |||
| 8170ffef2e | |||
| 4b622f6bbf | |||
| 0ee71c70af | |||
| 6c098e497e | |||
| 41ffa6df7e |
@@ -5,6 +5,9 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
schedule: [cron: "40 1 * * *"]
|
schedule: [cron: "40 1 * * *"]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RUSTFLAGS: -Dwarnings
|
RUSTFLAGS: -Dwarnings
|
||||||
|
|
||||||
@@ -12,6 +15,7 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
name: Test suite
|
name: Test suite
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@nightly
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
@@ -24,6 +28,7 @@ jobs:
|
|||||||
windows:
|
windows:
|
||||||
name: Test suite (windows)
|
name: Test suite (windows)
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@nightly
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
@@ -36,6 +41,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rust: [stable, beta]
|
rust: [stable, beta]
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@master
|
- uses: dtolnay/rust-toolchain@master
|
||||||
@@ -53,6 +59,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu, windows]
|
os: [ubuntu, windows]
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@nightly
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
@@ -71,12 +78,13 @@ jobs:
|
|||||||
msrv:
|
msrv:
|
||||||
name: Rust 1.13.0
|
name: Rust 1.13.0
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@1.13.0
|
- uses: dtolnay/rust-toolchain@1.13.0
|
||||||
- name: Get timestamp for cache
|
- name: Get timestamp for cache
|
||||||
id: date
|
id: date
|
||||||
run: echo ::set-output name=yearmo::$(date +%Y%m)
|
run: echo yearmo=$(date +%Y%m) >> $GITHUB_OUTPUT
|
||||||
- uses: actions/cache@v1
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/registry/index
|
path: ~/.cargo/registry/index
|
||||||
@@ -92,6 +100,7 @@ jobs:
|
|||||||
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.19.0, 1.20.0, 1.21.0, 1.25.0, 1.26.0, 1.34.0]
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@master
|
- uses: dtolnay/rust-toolchain@master
|
||||||
@@ -107,6 +116,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rust: [1.27.0, 1.28.0]
|
rust: [1.27.0, 1.28.0]
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@master
|
- uses: dtolnay/rust-toolchain@master
|
||||||
@@ -120,6 +130,7 @@ jobs:
|
|||||||
derive:
|
derive:
|
||||||
name: Rust 1.31.0
|
name: Rust 1.31.0
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@1.31.0
|
- uses: dtolnay/rust-toolchain@1.31.0
|
||||||
@@ -130,6 +141,7 @@ jobs:
|
|||||||
alloc:
|
alloc:
|
||||||
name: Rust 1.36.0
|
name: Rust 1.36.0
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@1.36.0
|
- uses: dtolnay/rust-toolchain@1.36.0
|
||||||
@@ -138,6 +150,7 @@ jobs:
|
|||||||
emscripten:
|
emscripten:
|
||||||
name: Emscripten
|
name: Emscripten
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@nightly
|
- uses: dtolnay/rust-toolchain@nightly
|
||||||
@@ -161,6 +174,7 @@ jobs:
|
|||||||
name: Clippy
|
name: Clippy
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@clippy
|
- uses: dtolnay/rust-toolchain@clippy
|
||||||
@@ -174,6 +188,7 @@ jobs:
|
|||||||
miri:
|
miri:
|
||||||
name: Miri
|
name: Miri
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/rust-toolchain@miri
|
- uses: dtolnay/rust-toolchain@miri
|
||||||
@@ -188,6 +203,7 @@ jobs:
|
|||||||
name: Outdated
|
name: Outdated
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: dtolnay/install@cargo-outdated
|
- uses: dtolnay/install@cargo-outdated
|
||||||
|
|||||||
+12
-12
@@ -1,21 +1,21 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.137" # remember to update html_root_url and serde_derive dependency
|
version = "1.0.149" # 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>"]
|
||||||
rust-version = "1.13"
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "A generic serialization/deserialization framework"
|
|
||||||
homepage = "https://serde.rs"
|
|
||||||
repository = "https://github.com/serde-rs/serde"
|
|
||||||
documentation = "https://docs.serde.rs/serde/"
|
|
||||||
keywords = ["serde", "serialization", "no_std"]
|
|
||||||
categories = ["encoding"]
|
|
||||||
readme = "crates-io.md"
|
|
||||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
categories = ["encoding", "no-std"]
|
||||||
|
description = "A generic serialization/deserialization framework"
|
||||||
|
documentation = "https://docs.serde.rs/serde/"
|
||||||
|
homepage = "https://serde.rs"
|
||||||
|
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
keywords = ["serde", "serialization", "no_std"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
readme = "crates-io.md"
|
||||||
|
repository = "https://github.com/serde-rs/serde"
|
||||||
|
rust-version = "1.13"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde_derive = { version = "=1.0.137", optional = true, path = "../serde_derive" }
|
serde_derive = { version = "=1.0.149", optional = true, path = "../serde_derive" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_derive = { version = "1.0", path = "../serde_derive" }
|
serde_derive = { version = "1.0", path = "../serde_derive" }
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ fn main() {
|
|||||||
println!("cargo:rustc-cfg=no_core_try_from");
|
println!("cargo:rustc-cfg=no_core_try_from");
|
||||||
println!("cargo:rustc-cfg=no_num_nonzero_signed");
|
println!("cargo:rustc-cfg=no_num_nonzero_signed");
|
||||||
println!("cargo:rustc-cfg=no_systemtime_checked_add");
|
println!("cargo:rustc-cfg=no_systemtime_checked_add");
|
||||||
|
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whitelist of archs that support std::sync::atomic module. Ideally we
|
// Whitelist of archs that support std::sync::atomic module. Ideally we
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use lib::fmt::{self, Write};
|
use lib::fmt::{self, Write};
|
||||||
use lib::str;
|
use lib::str;
|
||||||
|
|
||||||
pub struct Buf<'a> {
|
pub(super) struct Buf<'a> {
|
||||||
bytes: &'a mut [u8],
|
bytes: &'a mut [u8],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
|
|||||||
where
|
where
|
||||||
A: EnumAccess<'de>,
|
A: EnumAccess<'de>,
|
||||||
{
|
{
|
||||||
data.variant::<IgnoredAny>()?.1.newtype_variant()
|
try!(data.variant::<IgnoredAny>()).1.newtype_variant()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2268,14 +2268,14 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let (start, end) = deserializer.deserialize_struct(
|
let (start, end) = try!(deserializer.deserialize_struct(
|
||||||
"Range",
|
"Range",
|
||||||
range::FIELDS,
|
range::FIELDS,
|
||||||
range::RangeVisitor {
|
range::RangeVisitor {
|
||||||
expecting: "struct Range",
|
expecting: "struct Range",
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
},
|
},
|
||||||
)?;
|
));
|
||||||
Ok(start..end)
|
Ok(start..end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2289,14 +2289,14 @@ where
|
|||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let (start, end) = deserializer.deserialize_struct(
|
let (start, end) = try!(deserializer.deserialize_struct(
|
||||||
"RangeInclusive",
|
"RangeInclusive",
|
||||||
range::FIELDS,
|
range::FIELDS,
|
||||||
range::RangeVisitor {
|
range::RangeVisitor {
|
||||||
expecting: "struct RangeInclusive",
|
expecting: "struct RangeInclusive",
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
},
|
},
|
||||||
)?;
|
));
|
||||||
Ok(RangeInclusive::new(start, end))
|
Ok(RangeInclusive::new(start, end))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-12
@@ -30,7 +30,7 @@
|
|||||||
//! # The Deserializer trait
|
//! # The Deserializer trait
|
||||||
//!
|
//!
|
||||||
//! [`Deserializer`] implementations are provided by third-party crates, for
|
//! [`Deserializer`] implementations are provided by third-party crates, for
|
||||||
//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
|
//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
|
||||||
//!
|
//!
|
||||||
//! A partial list of well-maintained formats is given on the [Serde
|
//! A partial list of well-maintained formats is given on the [Serde
|
||||||
//! website][data formats].
|
//! website][data formats].
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
//! [`Deserialize`]: ../trait.Deserialize.html
|
//! [`Deserialize`]: ../trait.Deserialize.html
|
||||||
//! [`Deserializer`]: ../trait.Deserializer.html
|
//! [`Deserializer`]: ../trait.Deserializer.html
|
||||||
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
||||||
//! [`bincode`]: https://github.com/bincode-org/bincode
|
//! [`postcard`]: https://github.com/jamesmunns/postcard
|
||||||
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
||||||
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
||||||
//! [`serde_json`]: https://github.com/serde-rs/json
|
//! [`serde_json`]: https://github.com/serde-rs/json
|
||||||
@@ -565,7 +565,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 = Deserialize::deserialize(deserializer)?;
|
*place = try!(Deserialize::deserialize(deserializer));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -708,6 +708,11 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
|
|||||||
/// where
|
/// where
|
||||||
/// A: SeqAccess<'de>,
|
/// A: SeqAccess<'de>,
|
||||||
/// {
|
/// {
|
||||||
|
/// // Decrease the number of reallocations if there are many elements
|
||||||
|
/// if let Some(size_hint) = seq.size_hint() {
|
||||||
|
/// self.0.reserve(size_hint);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
/// // Visit each element in the inner array and push it onto
|
/// // Visit each element in the inner array and push it onto
|
||||||
/// // the existing vector.
|
/// // the existing vector.
|
||||||
/// while let Some(elem) = seq.next_element()? {
|
/// while let Some(elem) = seq.next_element()? {
|
||||||
@@ -857,10 +862,10 @@ where
|
|||||||
/// The `Deserializer` trait supports two entry point styles which enables
|
/// The `Deserializer` trait supports two entry point styles which enables
|
||||||
/// different kinds of deserialization.
|
/// different kinds of deserialization.
|
||||||
///
|
///
|
||||||
/// 1. The `deserialize` method. Self-describing data formats like JSON are able
|
/// 1. The `deserialize_any` method. Self-describing data formats like JSON are
|
||||||
/// to look at the serialized data and tell what it represents. For example
|
/// able to look at the serialized data and tell what it represents. For
|
||||||
/// the JSON deserializer may see an opening curly brace (`{`) and know that
|
/// example the JSON deserializer may see an opening curly brace (`{`) and
|
||||||
/// it is seeing a map. If the data format supports
|
/// know that it is seeing a map. If the data format supports
|
||||||
/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever
|
/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever
|
||||||
/// type it sees in the input. JSON uses this approach when deserializing
|
/// type it sees in the input. JSON uses this approach when deserializing
|
||||||
/// `serde_json::Value` which is an enum that can represent any JSON
|
/// `serde_json::Value` which is an enum that can represent any JSON
|
||||||
@@ -869,7 +874,7 @@ where
|
|||||||
/// `Deserializer::deserialize_any`.
|
/// `Deserializer::deserialize_any`.
|
||||||
///
|
///
|
||||||
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
|
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
|
||||||
/// Bincode need to be told what is in the input in order to deserialize it.
|
/// Postcard need to be told what is in the input in order to deserialize it.
|
||||||
/// The `deserialize_*` methods are hints to the deserializer for how to
|
/// The `deserialize_*` methods are hints to the deserializer for how to
|
||||||
/// interpret the next piece of input. Non-self-describing formats are not
|
/// interpret the next piece of input. Non-self-describing formats are not
|
||||||
/// able to deserialize something like `serde_json::Value` which relies on
|
/// able to deserialize something like `serde_json::Value` which relies on
|
||||||
@@ -879,7 +884,7 @@ where
|
|||||||
/// `Deserializer::deserialize_any` unless you need to be told by the
|
/// `Deserializer::deserialize_any` unless you need to be told by the
|
||||||
/// Deserializer what type is in the input. Know that relying on
|
/// Deserializer what type is in the input. Know that relying on
|
||||||
/// `Deserializer::deserialize_any` means your data type will be able to
|
/// `Deserializer::deserialize_any` means your data type will be able to
|
||||||
/// deserialize from self-describing formats only, ruling out Bincode and many
|
/// deserialize from self-describing formats only, ruling out Postcard and many
|
||||||
/// others.
|
/// others.
|
||||||
///
|
///
|
||||||
/// [Serde data model]: https://serde.rs/data-model.html
|
/// [Serde data model]: https://serde.rs/data-model.html
|
||||||
@@ -910,7 +915,7 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
/// `Deserializer::deserialize_any` unless you need to be told by the
|
/// `Deserializer::deserialize_any` unless you need to be told by the
|
||||||
/// Deserializer what type is in the input. Know that relying on
|
/// Deserializer what type is in the input. Know that relying on
|
||||||
/// `Deserializer::deserialize_any` means your data type will be able to
|
/// `Deserializer::deserialize_any` means your data type will be able to
|
||||||
/// deserialize from self-describing formats only, ruling out Bincode and
|
/// deserialize from self-describing formats only, ruling out Postcard and
|
||||||
/// many others.
|
/// many others.
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where
|
where
|
||||||
@@ -1151,7 +1156,7 @@ pub trait Deserializer<'de>: Sized {
|
|||||||
/// Some types have a human-readable form that may be somewhat expensive to
|
/// Some types have a human-readable form that may be somewhat expensive to
|
||||||
/// construct, as well as a binary form that is compact and efficient.
|
/// construct, as well as a binary form that is compact and efficient.
|
||||||
/// Generally text-based formats like JSON and YAML will prefer to use the
|
/// Generally text-based formats like JSON and YAML will prefer to use the
|
||||||
/// human-readable one and binary formats like Bincode will prefer the
|
/// human-readable one and binary formats like Postcard will prefer the
|
||||||
/// compact one.
|
/// compact one.
|
||||||
///
|
///
|
||||||
/// ```edition2018
|
/// ```edition2018
|
||||||
@@ -1555,7 +1560,7 @@ pub trait Visitor<'de>: Sized {
|
|||||||
/// `Deserializer`.
|
/// `Deserializer`.
|
||||||
///
|
///
|
||||||
/// This enables zero-copy deserialization of bytes in some formats. For
|
/// This enables zero-copy deserialization of bytes in some formats. For
|
||||||
/// example Bincode data containing bytes can be deserialized with zero
|
/// example Postcard data containing bytes can be deserialized with zero
|
||||||
/// copying into a `&'a [u8]` as long as the input data outlives `'a`.
|
/// copying into a `&'a [u8]` as long as the input data outlives `'a`.
|
||||||
///
|
///
|
||||||
/// The default implementation forwards to `visit_bytes`.
|
/// The default implementation forwards to `visit_bytes`.
|
||||||
|
|||||||
+88
-9
@@ -128,9 +128,7 @@ where
|
|||||||
type Deserializer = UnitDeserializer<E>;
|
type Deserializer = UnitDeserializer<E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> UnitDeserializer<E> {
|
fn into_deserializer(self) -> UnitDeserializer<E> {
|
||||||
UnitDeserializer {
|
UnitDeserializer::new()
|
||||||
marker: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,6 +139,15 @@ pub struct UnitDeserializer<E> {
|
|||||||
|
|
||||||
impl_copy_clone!(UnitDeserializer);
|
impl_copy_clone!(UnitDeserializer);
|
||||||
|
|
||||||
|
impl<E> UnitDeserializer<E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
UnitDeserializer {
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
|
impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
|
||||||
where
|
where
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
@@ -236,8 +243,15 @@ macro_rules! primitive_deserializer {
|
|||||||
type Deserializer = $name<E>;
|
type Deserializer = $name<E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> $name<E> {
|
fn into_deserializer(self) -> $name<E> {
|
||||||
|
$name::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> $name<E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new(value: $ty) -> Self {
|
||||||
$name {
|
$name {
|
||||||
value: self,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,8 +322,15 @@ where
|
|||||||
type Deserializer = U32Deserializer<E>;
|
type Deserializer = U32Deserializer<E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> U32Deserializer<E> {
|
fn into_deserializer(self) -> U32Deserializer<E> {
|
||||||
|
U32Deserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E> U32Deserializer<E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new(value: u32) -> Self {
|
||||||
U32Deserializer {
|
U32Deserializer {
|
||||||
value: self,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,8 +411,15 @@ where
|
|||||||
type Deserializer = StrDeserializer<'a, E>;
|
type Deserializer = StrDeserializer<'a, E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> StrDeserializer<'a, E> {
|
fn into_deserializer(self) -> StrDeserializer<'a, E> {
|
||||||
|
StrDeserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, E> StrDeserializer<'a, E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new(value: &'a str) -> Self {
|
||||||
StrDeserializer {
|
StrDeserializer {
|
||||||
value: self,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -561,8 +589,16 @@ where
|
|||||||
type Deserializer = StringDeserializer<E>;
|
type Deserializer = StringDeserializer<E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> StringDeserializer<E> {
|
fn into_deserializer(self) -> StringDeserializer<E> {
|
||||||
|
StringDeserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<E> StringDeserializer<E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new(value: String) -> Self {
|
||||||
StringDeserializer {
|
StringDeserializer {
|
||||||
value: self,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -656,8 +692,16 @@ where
|
|||||||
type Deserializer = CowStrDeserializer<'a, E>;
|
type Deserializer = CowStrDeserializer<'a, E>;
|
||||||
|
|
||||||
fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
|
fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
|
||||||
|
CowStrDeserializer::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
|
impl<'a, E> CowStrDeserializer<'a, E> {
|
||||||
|
#[allow(missing_docs)]
|
||||||
|
pub fn new(value: Cow<'a, str>) -> Self {
|
||||||
CowStrDeserializer {
|
CowStrDeserializer {
|
||||||
value: self,
|
value: value,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1457,7 +1501,7 @@ where
|
|||||||
where
|
where
|
||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match self.map.next_key_seed(seed)? {
|
match try!(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")),
|
||||||
}
|
}
|
||||||
@@ -1466,6 +1510,41 @@ where
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// A deserializer holding an `EnumAccess`.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct EnumAccessDeserializer<A> {
|
||||||
|
access: A,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> EnumAccessDeserializer<A> {
|
||||||
|
/// Construct a new `EnumAccessDeserializer<A>`.
|
||||||
|
pub fn new(access: A) -> Self {
|
||||||
|
EnumAccessDeserializer { access: access }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de, A> de::Deserializer<'de> for EnumAccessDeserializer<A>
|
||||||
|
where
|
||||||
|
A: de::EnumAccess<'de>,
|
||||||
|
{
|
||||||
|
type Error = A::Error;
|
||||||
|
|
||||||
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
where
|
||||||
|
V: de::Visitor<'de>,
|
||||||
|
{
|
||||||
|
visitor.visit_enum(self.access)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
mod private {
|
mod private {
|
||||||
use lib::*;
|
use lib::*;
|
||||||
|
|
||||||
|
|||||||
+20
-9
@@ -31,8 +31,7 @@
|
|||||||
//! for Serde by the community.
|
//! for Serde by the community.
|
||||||
//!
|
//!
|
||||||
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
|
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
|
||||||
//! - [Bincode], a compact binary format
|
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
|
||||||
//! used for IPC within the Servo rendering engine.
|
|
||||||
//! - [CBOR], a Concise Binary Object Representation designed for small message
|
//! - [CBOR], a Concise Binary Object Representation designed for small message
|
||||||
//! size without the need for version negotiation.
|
//! size without the need for version negotiation.
|
||||||
//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
|
//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
|
||||||
@@ -45,7 +44,6 @@
|
|||||||
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
|
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
|
||||||
//! definition.
|
//! definition.
|
||||||
//! - [JSON5], a superset of JSON including some productions from ES5.
|
//! - [JSON5], a superset of JSON including some productions from ES5.
|
||||||
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
|
|
||||||
//! - [URL] query strings, in the x-www-form-urlencoded format.
|
//! - [URL] query strings, in the x-www-form-urlencoded format.
|
||||||
//! - [Envy], a way to deserialize environment variables into Rust structs.
|
//! - [Envy], a way to deserialize environment variables into Rust structs.
|
||||||
//! *(deserialization only)*
|
//! *(deserialization only)*
|
||||||
@@ -59,17 +57,16 @@
|
|||||||
//! and from DynamoDB.
|
//! and from DynamoDB.
|
||||||
//!
|
//!
|
||||||
//! [JSON]: https://github.com/serde-rs/json
|
//! [JSON]: https://github.com/serde-rs/json
|
||||||
//! [Bincode]: https://github.com/bincode-org/bincode
|
//! [Postcard]: https://github.com/jamesmunns/postcard
|
||||||
//! [CBOR]: https://github.com/enarx/ciborium
|
//! [CBOR]: https://github.com/enarx/ciborium
|
||||||
//! [YAML]: https://github.com/dtolnay/serde-yaml
|
//! [YAML]: https://github.com/dtolnay/serde-yaml
|
||||||
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
|
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
|
||||||
//! [TOML]: https://github.com/alexcrichton/toml-rs
|
//! [TOML]: https://docs.rs/toml
|
||||||
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
|
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
|
||||||
//! [RON]: https://github.com/ron-rs/ron
|
//! [RON]: https://github.com/ron-rs/ron
|
||||||
//! [BSON]: https://github.com/mongodb/bson-rust
|
//! [BSON]: https://github.com/mongodb/bson-rust
|
||||||
//! [Avro]: https://github.com/flavray/avro-rs
|
//! [Avro]: https://docs.rs/apache-avro
|
||||||
//! [JSON5]: https://github.com/callum-oakley/json5-rs
|
//! [JSON5]: https://github.com/callum-oakley/json5-rs
|
||||||
//! [Postcard]: https://github.com/jamesmunns/postcard
|
|
||||||
//! [URL]: https://docs.rs/serde_qs
|
//! [URL]: https://docs.rs/serde_qs
|
||||||
//! [Envy]: https://github.com/softprops/envy
|
//! [Envy]: https://github.com/softprops/envy
|
||||||
//! [Envy Store]: https://github.com/softprops/envy-store
|
//! [Envy Store]: https://github.com/softprops/envy-store
|
||||||
@@ -84,7 +81,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.137")]
|
#![doc(html_root_url = "https://docs.rs/serde/1.0.149")]
|
||||||
// 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
|
||||||
@@ -120,8 +117,9 @@
|
|||||||
// correctly used
|
// correctly used
|
||||||
derive_partial_eq_without_eq,
|
derive_partial_eq_without_eq,
|
||||||
enum_glob_use,
|
enum_glob_use,
|
||||||
let_underscore_drop,
|
explicit_auto_deref,
|
||||||
map_err_ignore,
|
map_err_ignore,
|
||||||
|
new_without_default,
|
||||||
result_unit_err,
|
result_unit_err,
|
||||||
wildcard_imports,
|
wildcard_imports,
|
||||||
// not practical
|
// not practical
|
||||||
@@ -250,6 +248,19 @@ mod lib {
|
|||||||
pub use self::core::time::Duration;
|
pub use self::core::time::Duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// None of this crate's error handling needs the `From::from` error conversion
|
||||||
|
// performed implicitly by the `?` operator or the standard library's `try!`
|
||||||
|
// macro. This simplified macro gives a 5.5% improvement in compile time
|
||||||
|
// compared to standard `try!`, and 9% improvement compared to `?`.
|
||||||
|
macro_rules! try {
|
||||||
|
($expr:expr) => {
|
||||||
|
match $expr {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => return Err(err),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
+17
-6
@@ -1262,6 +1262,17 @@ mod content {
|
|||||||
{
|
{
|
||||||
match self.content {
|
match self.content {
|
||||||
Content::Unit => visitor.visit_unit(),
|
Content::Unit => visitor.visit_unit(),
|
||||||
|
|
||||||
|
// Allow deserializing newtype variant containing unit.
|
||||||
|
//
|
||||||
|
// #[derive(Deserialize)]
|
||||||
|
// #[serde(tag = "result")]
|
||||||
|
// enum Response<T> {
|
||||||
|
// Success(T),
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// We want {"result":"Success"} to deserialize into Response<()>.
|
||||||
|
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
|
||||||
_ => Err(self.invalid_type(&visitor)),
|
_ => Err(self.invalid_type(&visitor)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1799,7 +1810,7 @@ mod content {
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
{
|
{
|
||||||
let map = content.iter().map(|&(ref k, ref v)| {
|
let map = content.iter().map(|(k, v)| {
|
||||||
(
|
(
|
||||||
ContentRefDeserializer::new(k),
|
ContentRefDeserializer::new(k),
|
||||||
ContentRefDeserializer::new(v),
|
ContentRefDeserializer::new(v),
|
||||||
@@ -2096,7 +2107,7 @@ mod content {
|
|||||||
let (variant, value) = match *self.content {
|
let (variant, value) = match *self.content {
|
||||||
Content::Map(ref value) => {
|
Content::Map(ref value) => {
|
||||||
let mut iter = value.iter();
|
let mut iter = value.iter();
|
||||||
let &(ref variant, ref value) = match iter.next() {
|
let (variant, value) = match iter.next() {
|
||||||
Some(v) => v,
|
Some(v) => v,
|
||||||
None => {
|
None => {
|
||||||
return Err(de::Error::invalid_value(
|
return Err(de::Error::invalid_value(
|
||||||
@@ -2243,7 +2254,7 @@ mod content {
|
|||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(&Content::Seq(ref v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
@@ -2266,10 +2277,10 @@ mod content {
|
|||||||
V: de::Visitor<'de>,
|
V: de::Visitor<'de>,
|
||||||
{
|
{
|
||||||
match self.value {
|
match self.value {
|
||||||
Some(&Content::Map(ref v)) => {
|
Some(Content::Map(v)) => {
|
||||||
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(&Content::Seq(ref v)) => {
|
Some(Content::Seq(v)) => {
|
||||||
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
|
||||||
}
|
}
|
||||||
Some(other) => Err(de::Error::invalid_type(
|
Some(other) => Err(de::Error::invalid_type(
|
||||||
@@ -2392,7 +2403,7 @@ mod content {
|
|||||||
T: de::DeserializeSeed<'de>,
|
T: de::DeserializeSeed<'de>,
|
||||||
{
|
{
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(&(ref key, ref value)) => {
|
Some((key, value)) => {
|
||||||
self.value = Some(value);
|
self.value = Some(value);
|
||||||
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
|
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ enum Unsupported {
|
|||||||
String,
|
String,
|
||||||
ByteArray,
|
ByteArray,
|
||||||
Optional,
|
Optional,
|
||||||
Unit,
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
UnitStruct,
|
UnitStruct,
|
||||||
Sequence,
|
Sequence,
|
||||||
@@ -70,7 +69,6 @@ impl Display for Unsupported {
|
|||||||
Unsupported::String => formatter.write_str("a string"),
|
Unsupported::String => formatter.write_str("a string"),
|
||||||
Unsupported::ByteArray => formatter.write_str("a byte array"),
|
Unsupported::ByteArray => formatter.write_str("a byte array"),
|
||||||
Unsupported::Optional => formatter.write_str("an optional"),
|
Unsupported::Optional => formatter.write_str("an optional"),
|
||||||
Unsupported::Unit => formatter.write_str("unit"),
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
Unsupported::UnitStruct => formatter.write_str("unit struct"),
|
Unsupported::UnitStruct => formatter.write_str("unit struct"),
|
||||||
Unsupported::Sequence => formatter.write_str("a sequence"),
|
Unsupported::Sequence => formatter.write_str("a sequence"),
|
||||||
@@ -184,7 +182,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||||
Err(self.bad_type(Unsupported::Unit))
|
let mut map = try!(self.delegate.serialize_map(Some(1)));
|
||||||
|
try!(map.serialize_entry(self.tag, self.variant_name));
|
||||||
|
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> {
|
||||||
@@ -525,7 +525,7 @@ mod content {
|
|||||||
Content::Map(ref entries) => {
|
Content::Map(ref entries) => {
|
||||||
use ser::SerializeMap;
|
use ser::SerializeMap;
|
||||||
let mut map = try!(serializer.serialize_map(Some(entries.len())));
|
let mut map = try!(serializer.serialize_map(Some(entries.len())));
|
||||||
for &(ref k, ref v) in entries {
|
for (k, v) in entries {
|
||||||
try!(map.serialize_entry(k, v));
|
try!(map.serialize_entry(k, v));
|
||||||
}
|
}
|
||||||
map.end()
|
map.end()
|
||||||
|
|||||||
+30
-10
@@ -182,7 +182,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))]
|
||||||
|
macro_rules! seq_impl {
|
||||||
|
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
|
||||||
|
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
|
||||||
|
where
|
||||||
|
T: Serialize,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.collect_seq(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
|
||||||
macro_rules! seq_impl {
|
macro_rules! seq_impl {
|
||||||
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
|
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
|
||||||
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
|
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
|
||||||
@@ -522,7 +540,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Serialize for RefCell<T>
|
impl<T: ?Sized> Serialize for RefCell<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
@@ -538,7 +556,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T> Serialize for Mutex<T>
|
impl<T: ?Sized> Serialize for Mutex<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
@@ -554,7 +572,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T> Serialize for RwLock<T>
|
impl<T: ?Sized> Serialize for RwLock<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
@@ -614,9 +632,10 @@ impl Serialize for SystemTime {
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
use super::SerializeStruct;
|
use super::SerializeStruct;
|
||||||
let duration_since_epoch = self
|
let duration_since_epoch = match self.duration_since(UNIX_EPOCH) {
|
||||||
.duration_since(UNIX_EPOCH)
|
Ok(duration_since_epoch) => duration_since_epoch,
|
||||||
.map_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 = try!(serializer.serialize_struct("SystemTime", 2));
|
||||||
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||||
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||||
@@ -735,8 +754,9 @@ impl Serialize for net::Ipv4Addr {
|
|||||||
// Skip over delimiters that we initialized buf with
|
// Skip over delimiters that we initialized buf with
|
||||||
written += format_u8(*oct, &mut buf[written + 1..]) + 1;
|
written += format_u8(*oct, &mut buf[written + 1..]) + 1;
|
||||||
}
|
}
|
||||||
// We've only written ASCII bytes to the buffer, so it is valid UTF-8
|
// Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8
|
||||||
serializer.serialize_str(unsafe { str::from_utf8_unchecked(&buf[..written]) })
|
let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) };
|
||||||
|
serializer.serialize_str(buf)
|
||||||
} else {
|
} else {
|
||||||
self.octets().serialize(serializer)
|
self.octets().serialize(serializer)
|
||||||
}
|
}
|
||||||
@@ -916,7 +936,7 @@ macro_rules! atomic_impl {
|
|||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
// Matches the atomic ordering used in libcore for the Debug impl
|
// Matches the atomic ordering used in libcore for the Debug impl
|
||||||
self.load(Ordering::SeqCst).serialize(serializer)
|
self.load(Ordering::Relaxed).serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
//! # The Serializer trait
|
//! # The Serializer trait
|
||||||
//!
|
//!
|
||||||
//! [`Serializer`] implementations are provided by third-party crates, for
|
//! [`Serializer`] implementations are provided by third-party crates, for
|
||||||
//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
|
//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
|
||||||
//!
|
//!
|
||||||
//! A partial list of well-maintained formats is given on the [Serde
|
//! A partial list of well-maintained formats is given on the [Serde
|
||||||
//! website][data formats].
|
//! website][data formats].
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
|
||||||
//! [`Serialize`]: ../trait.Serialize.html
|
//! [`Serialize`]: ../trait.Serialize.html
|
||||||
//! [`Serializer`]: ../trait.Serializer.html
|
//! [`Serializer`]: ../trait.Serializer.html
|
||||||
//! [`bincode`]: https://github.com/bincode-org/bincode
|
//! [`postcard`]: https://github.com/jamesmunns/postcard
|
||||||
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
|
||||||
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
//! [`serde_derive`]: https://crates.io/crates/serde_derive
|
||||||
//! [`serde_json`]: https://github.com/serde-rs/json
|
//! [`serde_json`]: https://github.com/serde-rs/json
|
||||||
@@ -314,7 +314,7 @@ pub trait Serialize {
|
|||||||
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
|
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
|
||||||
///
|
///
|
||||||
/// Many Serde serializers produce text or binary data as output, for example
|
/// Many Serde serializers produce text or binary data as output, for example
|
||||||
/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
|
/// JSON or Postcard. This is not a requirement of the `Serializer` trait, and
|
||||||
/// there are serializers that do not produce text or binary output. One example
|
/// there are serializers that do not produce text or binary output. One example
|
||||||
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
|
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
|
||||||
/// serializer) that produces a `serde_json::Value` data structure in memory as
|
/// serializer) that produces a `serde_json::Value` data structure in memory as
|
||||||
@@ -1423,7 +1423,7 @@ pub trait Serializer: Sized {
|
|||||||
/// Some types have a human-readable form that may be somewhat expensive to
|
/// Some types have a human-readable form that may be somewhat expensive to
|
||||||
/// construct, as well as a binary form that is compact and efficient.
|
/// construct, as well as a binary form that is compact and efficient.
|
||||||
/// Generally text-based formats like JSON and YAML will prefer to use the
|
/// Generally text-based formats like JSON and YAML will prefer to use the
|
||||||
/// human-readable one and binary formats like Bincode will prefer the
|
/// human-readable one and binary formats like Postcard will prefer the
|
||||||
/// compact one.
|
/// compact one.
|
||||||
///
|
///
|
||||||
/// ```edition2018
|
/// ```edition2018
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.137" # remember to update html_root_url
|
version = "1.0.149" # 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>"]
|
||||||
rust-version = "1.31"
|
categories = ["no-std"]
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||||
homepage = "https://serde.rs"
|
|
||||||
repository = "https://github.com/serde-rs/serde"
|
|
||||||
documentation = "https://serde.rs/derive.html"
|
documentation = "https://serde.rs/derive.html"
|
||||||
keywords = ["serde", "serialization", "no_std"]
|
homepage = "https://serde.rs"
|
||||||
readme = "crates-io.md"
|
|
||||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
keywords = ["serde", "serialization", "no_std", "derive"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
readme = "crates-io.md"
|
||||||
|
repository = "https://github.com/serde-rs/serde"
|
||||||
|
rust-version = "1.31"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
@@ -23,7 +24,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = "1.0.90"
|
syn = "1.0.104"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0", path = "../serde" }
|
serde = { version = "1.0", path = "../serde" }
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ fn main() {
|
|||||||
|
|
||||||
// Underscore const names stabilized in Rust 1.37:
|
// Underscore const names stabilized in Rust 1.37:
|
||||||
// https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
|
// https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
|
||||||
if minor >= 37 {
|
if minor < 37 {
|
||||||
println!("cargo:rustc-cfg=underscore_consts");
|
println!("cargo:rustc-cfg=no_underscore_consts");
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ptr::addr_of! macro stabilized in Rust 1.51:
|
// The ptr::addr_of! macro stabilized in Rust 1.51:
|
||||||
// https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
|
// https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
|
||||||
if minor >= 51 {
|
if minor < 51 {
|
||||||
println!("cargo:rustc-cfg=ptr_addr_of");
|
println!("cargo:rustc-cfg=no_ptr_addr_of");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+98
-88
@@ -10,6 +10,7 @@ use fragment::{Expr, Fragment, Match, Stmts};
|
|||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
|
use internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
|
||||||
use pretend;
|
use pretend;
|
||||||
|
use this;
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -111,9 +112,13 @@ struct Parameters {
|
|||||||
local: syn::Ident,
|
local: syn::Ident,
|
||||||
|
|
||||||
/// Path to the type the impl is for. Either a single `Ident` for local
|
/// Path to the type the impl is for. Either a single `Ident` for local
|
||||||
/// types or `some::remote::Ident` for remote types. Does not include
|
/// types (does not include generic parameters) or `some::remote::Path` for
|
||||||
/// generic parameters.
|
/// remote types.
|
||||||
this: syn::Path,
|
this_type: syn::Path,
|
||||||
|
|
||||||
|
/// Same as `this_type` but using `::<T>` for generic parameters for use in
|
||||||
|
/// expression position.
|
||||||
|
this_value: syn::Path,
|
||||||
|
|
||||||
/// Generics including any explicit and inferred bounds for the impl.
|
/// Generics including any explicit and inferred bounds for the impl.
|
||||||
generics: syn::Generics,
|
generics: syn::Generics,
|
||||||
@@ -133,10 +138,8 @@ struct Parameters {
|
|||||||
impl Parameters {
|
impl Parameters {
|
||||||
fn new(cont: &Container) -> Self {
|
fn new(cont: &Container) -> Self {
|
||||||
let local = cont.ident.clone();
|
let local = cont.ident.clone();
|
||||||
let this = match cont.attrs.remote() {
|
let this_type = this::this_type(cont);
|
||||||
Some(remote) => remote.clone(),
|
let this_value = this::this_value(cont);
|
||||||
None => cont.ident.clone().into(),
|
|
||||||
};
|
|
||||||
let borrowed = borrowed_lifetimes(cont);
|
let borrowed = borrowed_lifetimes(cont);
|
||||||
let generics = build_generics(cont, &borrowed);
|
let generics = build_generics(cont, &borrowed);
|
||||||
let has_getter = cont.data.has_getter();
|
let has_getter = cont.data.has_getter();
|
||||||
@@ -144,7 +147,8 @@ impl Parameters {
|
|||||||
|
|
||||||
Parameters {
|
Parameters {
|
||||||
local,
|
local,
|
||||||
this,
|
this_type,
|
||||||
|
this_value,
|
||||||
generics,
|
generics,
|
||||||
borrowed,
|
borrowed,
|
||||||
has_getter,
|
has_getter,
|
||||||
@@ -155,7 +159,7 @@ impl Parameters {
|
|||||||
/// Type name to use in error messages and `&'static str` arguments to
|
/// Type name to use in error messages and `&'static str` arguments to
|
||||||
/// various Deserializer methods.
|
/// various Deserializer methods.
|
||||||
fn type_name(&self) -> String {
|
fn type_name(&self) -> String {
|
||||||
self.this.segments.last().unwrap().ident.to_string()
|
self.this_type.segments.last().unwrap().ident.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +362,7 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
|
|||||||
Data::Enum(_) => unreachable!(),
|
Data::Enum(_) => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
|
let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
|
||||||
|
|
||||||
let path = match transparent_field.attrs.deserialize_with() {
|
let path = match transparent_field.attrs.deserialize_with() {
|
||||||
@@ -386,7 +390,7 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
|
|||||||
quote_block! {
|
quote_block! {
|
||||||
_serde::__private::Result::map(
|
_serde::__private::Result::map(
|
||||||
#path(__deserializer),
|
#path(__deserializer),
|
||||||
|__transparent| #this { #(#assign),* })
|
|__transparent| #this_value { #(#assign),* })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +411,8 @@ fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
|
fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let this_value = ¶ms.this_value;
|
||||||
let type_name = cattrs.name().deserialize_name();
|
let type_name = cattrs.name().deserialize_name();
|
||||||
|
|
||||||
let expecting = format!("unit struct {}", params.type_name());
|
let expecting = format!("unit struct {}", params.type_name());
|
||||||
@@ -417,7 +422,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
|
|||||||
struct __Visitor;
|
struct __Visitor;
|
||||||
|
|
||||||
impl<'de> _serde::de::Visitor<'de> for __Visitor {
|
impl<'de> _serde::de::Visitor<'de> for __Visitor {
|
||||||
type Value = #this;
|
type Value = #this_type;
|
||||||
|
|
||||||
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
@@ -428,7 +433,7 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra
|
|||||||
where
|
where
|
||||||
__E: _serde::de::Error,
|
__E: _serde::de::Error,
|
||||||
{
|
{
|
||||||
_serde::__private::Ok(#this)
|
_serde::__private::Ok(#this_value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +448,8 @@ fn deserialize_tuple(
|
|||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
deserializer: Option<TokenStream>,
|
deserializer: Option<TokenStream>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let this_value = ¶ms.this_value;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -457,7 +463,7 @@ fn deserialize_tuple(
|
|||||||
let local = ¶ms.local;
|
let local = ¶ms.local;
|
||||||
quote!(#local)
|
quote!(#local)
|
||||||
} else {
|
} else {
|
||||||
quote!(#this)
|
quote!(#this_value)
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
@@ -485,7 +491,7 @@ fn deserialize_tuple(
|
|||||||
|
|
||||||
let visitor_expr = quote! {
|
let visitor_expr = quote! {
|
||||||
__Visitor {
|
__Visitor {
|
||||||
marker: _serde::__private::PhantomData::<#this #ty_generics>,
|
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData,
|
lifetime: _serde::__private::PhantomData,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -510,12 +516,12 @@ fn deserialize_tuple(
|
|||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
struct __Visitor #de_impl_generics #where_clause {
|
struct __Visitor #de_impl_generics #where_clause {
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
@@ -544,7 +550,7 @@ fn deserialize_tuple_in_place(
|
|||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
deserializer: Option<TokenStream>,
|
deserializer: Option<TokenStream>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -600,7 +606,7 @@ fn deserialize_tuple_in_place(
|
|||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
struct __Visitor #in_place_impl_generics #where_clause {
|
struct __Visitor #in_place_impl_generics #where_clause {
|
||||||
place: &#place_life mut #this #ty_generics,
|
place: &#place_life mut #this_type #ty_generics,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -705,9 +711,10 @@ fn deserialize_seq(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if params.has_getter {
|
if params.has_getter {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let (_, ty_generics, _) = params.generics.split_for_impl();
|
||||||
result = quote! {
|
result = quote! {
|
||||||
_serde::__private::Into::<#this>::into(#result)
|
_serde::__private::Into::<#this_type #ty_generics>::into(#result)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,14 +808,14 @@ fn deserialize_seq_in_place(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (_, ty_generics, _) = params.generics.split_for_impl();
|
let (_, ty_generics, _) = params.generics.split_for_impl();
|
||||||
let let_default = match cattrs.default() {
|
let let_default = match cattrs.default() {
|
||||||
attr::Default::Default => Some(quote!(
|
attr::Default::Default => Some(quote!(
|
||||||
let __default: #this #ty_generics = _serde::__private::Default::default();
|
let __default: #this_type #ty_generics = _serde::__private::Default::default();
|
||||||
)),
|
)),
|
||||||
attr::Default::Path(path) => Some(quote!(
|
attr::Default::Path(path) => Some(quote!(
|
||||||
let __default: #this #ty_generics = #path();
|
let __default: #this_type #ty_generics = #path();
|
||||||
)),
|
)),
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
@@ -849,9 +856,10 @@ fn deserialize_newtype_struct(
|
|||||||
|
|
||||||
let mut result = quote!(#type_path(__field0));
|
let mut result = quote!(#type_path(__field0));
|
||||||
if params.has_getter {
|
if params.has_getter {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let (_, ty_generics, _) = params.generics.split_for_impl();
|
||||||
result = quote! {
|
result = quote! {
|
||||||
_serde::__private::Into::<#this>::into(#result)
|
_serde::__private::Into::<#this_type #ty_generics>::into(#result)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +909,8 @@ fn deserialize_struct(
|
|||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let is_enum = variant_ident.is_some();
|
let is_enum = variant_ident.is_some();
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let this_value = ¶ms.this_value;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -913,7 +922,7 @@ fn deserialize_struct(
|
|||||||
let local = ¶ms.local;
|
let local = ¶ms.local;
|
||||||
quote!(#local)
|
quote!(#local)
|
||||||
} else {
|
} else {
|
||||||
quote!(#this)
|
quote!(#this_value)
|
||||||
};
|
};
|
||||||
|
|
||||||
let type_path = match variant_ident {
|
let type_path = match variant_ident {
|
||||||
@@ -941,7 +950,7 @@ fn deserialize_struct(
|
|||||||
|
|
||||||
let visitor_expr = quote! {
|
let visitor_expr = quote! {
|
||||||
__Visitor {
|
__Visitor {
|
||||||
marker: _serde::__private::PhantomData::<#this #ty_generics>,
|
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData,
|
lifetime: _serde::__private::PhantomData,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -993,7 +1002,7 @@ fn deserialize_struct(
|
|||||||
let visitor_seed = if is_enum && cattrs.has_flatten() {
|
let visitor_seed = if is_enum && cattrs.has_flatten() {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
|
fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
|
||||||
where
|
where
|
||||||
@@ -1011,12 +1020,12 @@ fn deserialize_struct(
|
|||||||
#field_visitor
|
#field_visitor
|
||||||
|
|
||||||
struct __Visitor #de_impl_generics #where_clause {
|
struct __Visitor #de_impl_generics #where_clause {
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
@@ -1057,7 +1066,7 @@ fn deserialize_struct_in_place(
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -1123,7 +1132,7 @@ fn deserialize_struct_in_place(
|
|||||||
#field_visitor
|
#field_visitor
|
||||||
|
|
||||||
struct __Visitor #in_place_impl_generics #where_clause {
|
struct __Visitor #in_place_impl_generics #where_clause {
|
||||||
place: &#place_life mut #this #ty_generics,
|
place: &#place_life mut #this_type #ty_generics,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1212,7 +1221,7 @@ fn deserialize_externally_tagged_enum(
|
|||||||
variants: &[Variant],
|
variants: &[Variant],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -1266,12 +1275,12 @@ fn deserialize_externally_tagged_enum(
|
|||||||
#variant_visitor
|
#variant_visitor
|
||||||
|
|
||||||
struct __Visitor #de_impl_generics #where_clause {
|
struct __Visitor #de_impl_generics #where_clause {
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
@@ -1292,7 +1301,7 @@ fn deserialize_externally_tagged_enum(
|
|||||||
#type_name,
|
#type_name,
|
||||||
VARIANTS,
|
VARIANTS,
|
||||||
__Visitor {
|
__Visitor {
|
||||||
marker: _serde::__private::PhantomData::<#this #ty_generics>,
|
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData,
|
lifetime: _serde::__private::PhantomData,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -1354,7 +1363,8 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
tag: &str,
|
tag: &str,
|
||||||
content: &str,
|
content: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let this_value = ¶ms.this_value;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -1415,13 +1425,13 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
|
|
||||||
let arm = match variant.style {
|
let arm = match variant.style {
|
||||||
Style::Unit => quote! {
|
Style::Unit => quote! {
|
||||||
_serde::__private::Ok(#this::#variant_ident)
|
_serde::__private::Ok(#this_value::#variant_ident)
|
||||||
},
|
},
|
||||||
Style::Newtype if variant.attrs.deserialize_with().is_none() => {
|
Style::Newtype if variant.attrs.deserialize_with().is_none() => {
|
||||||
let span = variant.original.span();
|
let span = variant.original.span();
|
||||||
let func = quote_spanned!(span=> _serde::__private::de::missing_field);
|
let func = quote_spanned!(span=> _serde::__private::de::missing_field);
|
||||||
quote! {
|
quote! {
|
||||||
#func(#content).map(#this::#variant_ident)
|
#func(#content).map(#this_value::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -1513,12 +1523,12 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
|
|
||||||
struct __Seed #de_impl_generics #where_clause {
|
struct __Seed #de_impl_generics #where_clause {
|
||||||
field: __Field,
|
field: __Field,
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
|
fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
|
||||||
where
|
where
|
||||||
@@ -1531,12 +1541,12 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct __Visitor #de_impl_generics #where_clause {
|
struct __Visitor #de_impl_generics #where_clause {
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
|
||||||
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
_serde::__private::Formatter::write_str(__formatter, #expecting)
|
||||||
@@ -1638,7 +1648,7 @@ fn deserialize_adjacently_tagged_enum(
|
|||||||
#type_name,
|
#type_name,
|
||||||
FIELDS,
|
FIELDS,
|
||||||
__Visitor {
|
__Visitor {
|
||||||
marker: _serde::__private::PhantomData::<#this #ty_generics>,
|
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData,
|
lifetime: _serde::__private::PhantomData,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -1707,10 +1717,10 @@ fn deserialize_externally_tagged_variant(
|
|||||||
|
|
||||||
match variant.style {
|
match variant.style {
|
||||||
Style::Unit => {
|
Style::Unit => {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
quote_block! {
|
quote_block! {
|
||||||
try!(_serde::de::VariantAccess::unit_variant(__variant));
|
try!(_serde::de::VariantAccess::unit_variant(__variant));
|
||||||
_serde::__private::Ok(#this::#variant_ident)
|
_serde::__private::Ok(#this_value::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => deserialize_externally_tagged_newtype_variant(
|
Style::Newtype => deserialize_externally_tagged_newtype_variant(
|
||||||
@@ -1749,7 +1759,7 @@ fn deserialize_internally_tagged_variant(
|
|||||||
|
|
||||||
match effective_style(variant) {
|
match effective_style(variant) {
|
||||||
Style::Unit => {
|
Style::Unit => {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let type_name = params.type_name();
|
let type_name = params.type_name();
|
||||||
let variant_name = variant.ident.to_string();
|
let variant_name = variant.ident.to_string();
|
||||||
let default = variant.fields.get(0).map(|field| {
|
let default = variant.fields.get(0).map(|field| {
|
||||||
@@ -1758,7 +1768,7 @@ fn deserialize_internally_tagged_variant(
|
|||||||
});
|
});
|
||||||
quote_block! {
|
quote_block! {
|
||||||
try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
|
try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
|
||||||
_serde::__private::Ok(#this::#variant_ident #default)
|
_serde::__private::Ok(#this_value::#variant_ident #default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => deserialize_untagged_newtype_variant(
|
Style::Newtype => deserialize_untagged_newtype_variant(
|
||||||
@@ -1796,7 +1806,7 @@ fn deserialize_untagged_variant(
|
|||||||
|
|
||||||
match effective_style(variant) {
|
match effective_style(variant) {
|
||||||
Style::Unit => {
|
Style::Unit => {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let type_name = params.type_name();
|
let type_name = params.type_name();
|
||||||
let variant_name = variant.ident.to_string();
|
let variant_name = variant.ident.to_string();
|
||||||
let default = variant.fields.get(0).map(|field| {
|
let default = variant.fields.get(0).map(|field| {
|
||||||
@@ -1808,7 +1818,7 @@ fn deserialize_untagged_variant(
|
|||||||
#deserializer,
|
#deserializer,
|
||||||
_serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
|
_serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
|
||||||
) {
|
) {
|
||||||
_serde::__private::Ok(()) => _serde::__private::Ok(#this::#variant_ident #default),
|
_serde::__private::Ok(()) => _serde::__private::Ok(#this_value::#variant_ident #default),
|
||||||
_serde::__private::Err(__err) => _serde::__private::Err(__err),
|
_serde::__private::Err(__err) => _serde::__private::Err(__err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1843,14 +1853,13 @@ fn deserialize_externally_tagged_newtype_variant(
|
|||||||
field: &Field,
|
field: &Field,
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
|
|
||||||
if field.attrs.skip_deserializing() {
|
if field.attrs.skip_deserializing() {
|
||||||
let this = ¶ms.this;
|
|
||||||
let default = Expr(expr_is_missing(field, cattrs));
|
let default = Expr(expr_is_missing(field, cattrs));
|
||||||
return quote_block! {
|
return quote_block! {
|
||||||
try!(_serde::de::VariantAccess::unit_variant(__variant));
|
try!(_serde::de::VariantAccess::unit_variant(__variant));
|
||||||
_serde::__private::Ok(#this::#variant_ident(#default))
|
_serde::__private::Ok(#this_value::#variant_ident(#default))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1861,7 +1870,7 @@ fn deserialize_externally_tagged_newtype_variant(
|
|||||||
let func =
|
let func =
|
||||||
quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
|
quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
|
||||||
quote_expr! {
|
quote_expr! {
|
||||||
_serde::__private::Result::map(#func(__variant), #this::#variant_ident)
|
_serde::__private::Result::map(#func(__variant), #this_value::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
@@ -1870,7 +1879,7 @@ fn deserialize_externally_tagged_newtype_variant(
|
|||||||
#wrapper
|
#wrapper
|
||||||
_serde::__private::Result::map(
|
_serde::__private::Result::map(
|
||||||
_serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
|
_serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
|
||||||
|__wrapper| #this::#variant_ident(__wrapper.value))
|
|__wrapper| #this_value::#variant_ident(__wrapper.value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1882,20 +1891,20 @@ fn deserialize_untagged_newtype_variant(
|
|||||||
field: &Field,
|
field: &Field,
|
||||||
deserializer: &TokenStream,
|
deserializer: &TokenStream,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let field_ty = field.ty;
|
let field_ty = field.ty;
|
||||||
match field.attrs.deserialize_with() {
|
match field.attrs.deserialize_with() {
|
||||||
None => {
|
None => {
|
||||||
let span = field.original.span();
|
let span = field.original.span();
|
||||||
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
|
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
|
||||||
quote_expr! {
|
quote_expr! {
|
||||||
_serde::__private::Result::map(#func(#deserializer), #this::#variant_ident)
|
_serde::__private::Result::map(#func(#deserializer), #this_value::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
quote_block! {
|
quote_block! {
|
||||||
let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer);
|
let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer);
|
||||||
_serde::__private::Result::map(__value, #this::#variant_ident)
|
_serde::__private::Result::map(__value, #this_value::#variant_ident)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1907,7 +1916,7 @@ fn deserialize_generated_identifier(
|
|||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
other_idx: Option<usize>,
|
other_idx: Option<usize>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = 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, fallthrough) = if !is_variant && cattrs.has_flatten() {
|
||||||
@@ -1927,7 +1936,7 @@ fn deserialize_generated_identifier(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let visitor_impl = Stmts(deserialize_identifier(
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
&this,
|
&this_value,
|
||||||
fields,
|
fields,
|
||||||
is_variant,
|
is_variant,
|
||||||
fallthrough,
|
fallthrough,
|
||||||
@@ -1982,8 +1991,8 @@ fn deserialize_custom_identifier(
|
|||||||
attr::Identifier::No => unreachable!(),
|
attr::Identifier::No => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_type = params.this_type.to_token_stream();
|
||||||
let this = quote!(#this);
|
let this_value = params.this_value.to_token_stream();
|
||||||
|
|
||||||
let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
|
let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
|
||||||
let last_ident = &last.ident;
|
let last_ident = &last.ident;
|
||||||
@@ -1992,7 +2001,7 @@ fn deserialize_custom_identifier(
|
|||||||
// last variant (checked in `check_identifier`), so all preceding
|
// last variant (checked in `check_identifier`), so all preceding
|
||||||
// are ordinary variants.
|
// are ordinary variants.
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
let fallthrough = quote!(_serde::__private::Ok(#this::#last_ident));
|
let fallthrough = quote!(_serde::__private::Ok(#this_value::#last_ident));
|
||||||
(ordinary, Some(fallthrough), None)
|
(ordinary, Some(fallthrough), None)
|
||||||
} else if let Style::Newtype = last.style {
|
} else if let Style::Newtype = last.style {
|
||||||
let ordinary = &variants[..variants.len() - 1];
|
let ordinary = &variants[..variants.len() - 1];
|
||||||
@@ -2002,7 +2011,7 @@ fn deserialize_custom_identifier(
|
|||||||
_serde::Deserialize::deserialize(
|
_serde::Deserialize::deserialize(
|
||||||
_serde::__private::de::IdentifierDeserializer::from(#value)
|
_serde::__private::de::IdentifierDeserializer::from(#value)
|
||||||
),
|
),
|
||||||
#this::#last_ident)
|
#this_value::#last_ident)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(
|
(
|
||||||
@@ -2050,7 +2059,7 @@ fn deserialize_custom_identifier(
|
|||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
let visitor_impl = Stmts(deserialize_identifier(
|
let visitor_impl = Stmts(deserialize_identifier(
|
||||||
&this,
|
&this_value,
|
||||||
&names_idents,
|
&names_idents,
|
||||||
is_variant,
|
is_variant,
|
||||||
fallthrough,
|
fallthrough,
|
||||||
@@ -2063,18 +2072,18 @@ fn deserialize_custom_identifier(
|
|||||||
#names_const
|
#names_const
|
||||||
|
|
||||||
struct __FieldVisitor #de_impl_generics #where_clause {
|
struct __FieldVisitor #de_impl_generics #where_clause {
|
||||||
marker: _serde::__private::PhantomData<#this #ty_generics>,
|
marker: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
|
impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
|
||||||
type Value = #this #ty_generics;
|
type Value = #this_type #ty_generics;
|
||||||
|
|
||||||
#visitor_impl
|
#visitor_impl
|
||||||
}
|
}
|
||||||
|
|
||||||
let __visitor = __FieldVisitor {
|
let __visitor = __FieldVisitor {
|
||||||
marker: _serde::__private::PhantomData::<#this #ty_generics>,
|
marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData,
|
lifetime: _serde::__private::PhantomData,
|
||||||
};
|
};
|
||||||
_serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
|
_serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
|
||||||
@@ -2082,7 +2091,7 @@ fn deserialize_custom_identifier(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_identifier(
|
fn deserialize_identifier(
|
||||||
this: &TokenStream,
|
this_value: &TokenStream,
|
||||||
fields: &[(String, Ident, Vec<String>)],
|
fields: &[(String, Ident, Vec<String>)],
|
||||||
is_variant: bool,
|
is_variant: bool,
|
||||||
fallthrough: Option<TokenStream>,
|
fallthrough: Option<TokenStream>,
|
||||||
@@ -2103,11 +2112,11 @@ fn deserialize_identifier(
|
|||||||
|
|
||||||
let constructors: &Vec<_> = &flat_fields
|
let constructors: &Vec<_> = &flat_fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, ident)| quote!(#this::#ident))
|
.map(|(_, ident)| quote!(#this_value::#ident))
|
||||||
.collect();
|
.collect();
|
||||||
let main_constructors: &Vec<_> = &fields
|
let main_constructors: &Vec<_> = &fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, ident, _)| quote!(#this::#ident))
|
.map(|(_, ident, _)| quote!(#this_value::#ident))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let expecting = expecting.unwrap_or(if is_variant {
|
let expecting = expecting.unwrap_or(if is_variant {
|
||||||
@@ -2621,9 +2630,10 @@ fn deserialize_map(
|
|||||||
|
|
||||||
let mut result = quote!(#struct_path { #(#result),* });
|
let mut result = quote!(#struct_path { #(#result),* });
|
||||||
if params.has_getter {
|
if params.has_getter {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
|
let (_, ty_generics, _) = params.generics.split_for_impl();
|
||||||
result = quote! {
|
result = quote! {
|
||||||
_serde::__private::Into::<#this>::into(#result)
|
_serde::__private::Into::<#this_type #ty_generics>::into(#result)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2803,15 +2813,15 @@ fn deserialize_map_in_place(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (_, _, ty_generics, _) = split_with_de_lifetime(params);
|
let (_, _, ty_generics, _) = split_with_de_lifetime(params);
|
||||||
|
|
||||||
let let_default = match cattrs.default() {
|
let let_default = match cattrs.default() {
|
||||||
attr::Default::Default => Some(quote!(
|
attr::Default::Default => Some(quote!(
|
||||||
let __default: #this #ty_generics = _serde::__private::Default::default();
|
let __default: #this_type #ty_generics = _serde::__private::Default::default();
|
||||||
)),
|
)),
|
||||||
attr::Default::Path(path) => Some(quote!(
|
attr::Default::Path(path) => Some(quote!(
|
||||||
let __default: #this #ty_generics = #path();
|
let __default: #this_type #ty_generics = #path();
|
||||||
)),
|
)),
|
||||||
attr::Default::None => {
|
attr::Default::None => {
|
||||||
// We don't need the default value, to prevent an unused variable warning
|
// We don't need the default value, to prevent an unused variable warning
|
||||||
@@ -2844,7 +2854,7 @@ fn wrap_deserialize_with(
|
|||||||
value_ty: &TokenStream,
|
value_ty: &TokenStream,
|
||||||
deserialize_with: &syn::ExprPath,
|
deserialize_with: &syn::ExprPath,
|
||||||
) -> (TokenStream, TokenStream) {
|
) -> (TokenStream, TokenStream) {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
|
||||||
split_with_de_lifetime(params);
|
split_with_de_lifetime(params);
|
||||||
let delife = params.borrowed.de_lifetime();
|
let delife = params.borrowed.de_lifetime();
|
||||||
@@ -2852,7 +2862,7 @@ fn wrap_deserialize_with(
|
|||||||
let wrapper = quote! {
|
let wrapper = quote! {
|
||||||
struct __DeserializeWith #de_impl_generics #where_clause {
|
struct __DeserializeWith #de_impl_generics #where_clause {
|
||||||
value: #value_ty,
|
value: #value_ty,
|
||||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
lifetime: _serde::__private::PhantomData<&#delife ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2903,7 +2913,7 @@ fn unwrap_to_variant_closure(
|
|||||||
variant: &Variant,
|
variant: &Variant,
|
||||||
with_wrapper: bool,
|
with_wrapper: bool,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let variant_ident = &variant.ident;
|
let variant_ident = &variant.ident;
|
||||||
|
|
||||||
let (arg, wrapper) = if with_wrapper {
|
let (arg, wrapper) = if with_wrapper {
|
||||||
@@ -2924,23 +2934,23 @@ fn unwrap_to_variant_closure(
|
|||||||
Style::Struct if variant.fields.len() == 1 => {
|
Style::Struct if variant.fields.len() == 1 => {
|
||||||
let member = &variant.fields[0].member;
|
let member = &variant.fields[0].member;
|
||||||
quote! {
|
quote! {
|
||||||
|#arg| #this::#variant_ident { #member: #wrapper }
|
|#arg| #this_value::#variant_ident { #member: #wrapper }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
Style::Struct => {
|
||||||
let members = variant.fields.iter().map(|field| &field.member);
|
let members = variant.fields.iter().map(|field| &field.member);
|
||||||
quote! {
|
quote! {
|
||||||
|#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* }
|
|#arg| #this_value::#variant_ident { #(#members: #wrapper.#field_access),* }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Tuple => quote! {
|
Style::Tuple => quote! {
|
||||||
|#arg| #this::#variant_ident(#(#wrapper.#field_access),*)
|
|#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*)
|
||||||
},
|
},
|
||||||
Style::Newtype => quote! {
|
Style::Newtype => quote! {
|
||||||
|#arg| #this::#variant_ident(#wrapper)
|
|#arg| #this_value::#variant_ident(#wrapper)
|
||||||
},
|
},
|
||||||
Style::Unit => quote! {
|
Style::Unit => quote! {
|
||||||
|#arg| #this::#variant_ident
|
|#arg| #this_value::#variant_ident
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ pub fn wrap_in_const(
|
|||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let try_replacement = try::replacement();
|
let try_replacement = try::replacement();
|
||||||
|
|
||||||
let dummy_const = if cfg!(underscore_consts) {
|
let dummy_const = if cfg!(no_underscore_consts) {
|
||||||
format_ident!("_")
|
|
||||||
} else {
|
|
||||||
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
|
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
|
||||||
|
} else {
|
||||||
|
format_ident!("_")
|
||||||
};
|
};
|
||||||
|
|
||||||
let use_serde = match serde_path {
|
let use_serde = match serde_path {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use syn::{Member, Type};
|
|||||||
/// Cross-cutting checks that require looking at more than a single attrs
|
/// Cross-cutting checks that require looking at more than a single attrs
|
||||||
/// object. Simpler checks should happen when parsing and building the attrs.
|
/// object. Simpler checks should happen when parsing and building the attrs.
|
||||||
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
||||||
|
check_remote_generic(cx, cont);
|
||||||
check_getter(cx, cont);
|
check_getter(cx, cont);
|
||||||
check_flatten(cx, cont);
|
check_flatten(cx, cont);
|
||||||
check_identifier(cx, cont);
|
check_identifier(cx, cont);
|
||||||
@@ -16,6 +17,28 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
|
|||||||
check_from_and_try_from(cx, cont);
|
check_from_and_try_from(cx, cont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remote derive definition type must have either all of the generics of the
|
||||||
|
/// remote type:
|
||||||
|
///
|
||||||
|
/// #[serde(remote = "Generic")]
|
||||||
|
/// struct Generic<T> {…}
|
||||||
|
///
|
||||||
|
/// or none of them, i.e. defining impls for one concrete instantiation of the
|
||||||
|
/// remote type only:
|
||||||
|
///
|
||||||
|
/// #[serde(remote = "Generic<T>")]
|
||||||
|
/// struct ConcreteDef {…}
|
||||||
|
///
|
||||||
|
fn check_remote_generic(cx: &Ctxt, cont: &Container) {
|
||||||
|
if let Some(remote) = cont.attrs.remote() {
|
||||||
|
let local_has_generic = !cont.generics.params.is_empty();
|
||||||
|
let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none();
|
||||||
|
if local_has_generic && remote_has_generic {
|
||||||
|
cx.error_spanned_by(remote, "remove generic parameters from this path");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Getters are only allowed inside structs (not enums) with the `remote`
|
/// Getters are only allowed inside structs (not enums) with the `remote`
|
||||||
/// attribute.
|
/// attribute.
|
||||||
fn check_getter(cx: &Ctxt, cont: &Container) {
|
fn check_getter(cx: &Ctxt, cont: &Container) {
|
||||||
|
|||||||
@@ -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.137")]
|
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.149")]
|
||||||
#![allow(unknown_lints, bare_trait_objects)]
|
#![allow(unknown_lints, bare_trait_objects)]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
#![allow(
|
#![allow(
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
clippy::enum_glob_use,
|
clippy::enum_glob_use,
|
||||||
clippy::indexing_slicing,
|
clippy::indexing_slicing,
|
||||||
clippy::items_after_statements,
|
clippy::items_after_statements,
|
||||||
clippy::let_underscore_drop,
|
|
||||||
clippy::manual_assert,
|
clippy::manual_assert,
|
||||||
clippy::map_err_ignore,
|
clippy::map_err_ignore,
|
||||||
clippy::match_same_arms,
|
clippy::match_same_arms,
|
||||||
@@ -85,6 +84,7 @@ mod de;
|
|||||||
mod dummy;
|
mod dummy;
|
||||||
mod pretend;
|
mod pretend;
|
||||||
mod ser;
|
mod ser;
|
||||||
|
mod this;
|
||||||
mod try;
|
mod try;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize, attributes(serde))]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> Toke
|
|||||||
|
|
||||||
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
|
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
|
||||||
|
|
||||||
#[cfg(ptr_addr_of)]
|
#[cfg(not(no_ptr_addr_of))]
|
||||||
{
|
{
|
||||||
quote! {
|
quote! {
|
||||||
match _serde::__private::None::<&#type_ident #ty_generics> {
|
match _serde::__private::None::<&#type_ident #ty_generics> {
|
||||||
@@ -111,7 +111,7 @@ fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> Toke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(ptr_addr_of))]
|
#[cfg(no_ptr_addr_of)]
|
||||||
{
|
{
|
||||||
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
|
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
|
||||||
|
|
||||||
|
|||||||
+32
-30
@@ -8,6 +8,7 @@ use fragment::{Fragment, Match, Stmts};
|
|||||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
use internals::{attr, replace_receiver, Ctxt, Derive};
|
use internals::{attr, replace_receiver, Ctxt, Derive};
|
||||||
use pretend;
|
use pretend;
|
||||||
|
use this;
|
||||||
|
|
||||||
pub fn expand_derive_serialize(
|
pub fn expand_derive_serialize(
|
||||||
input: &mut syn::DeriveInput,
|
input: &mut syn::DeriveInput,
|
||||||
@@ -82,9 +83,13 @@ struct Parameters {
|
|||||||
self_var: Ident,
|
self_var: Ident,
|
||||||
|
|
||||||
/// Path to the type the impl is for. Either a single `Ident` for local
|
/// Path to the type the impl is for. Either a single `Ident` for local
|
||||||
/// types or `some::remote::Ident` for remote types. Does not include
|
/// types (does not include generic parameters) or `some::remote::Path` for
|
||||||
/// generic parameters.
|
/// remote types.
|
||||||
this: syn::Path,
|
this_type: syn::Path,
|
||||||
|
|
||||||
|
/// Same as `this_type` but using `::<T>` for generic parameters for use in
|
||||||
|
/// expression position.
|
||||||
|
this_value: syn::Path,
|
||||||
|
|
||||||
/// Generics including any explicit and inferred bounds for the impl.
|
/// Generics including any explicit and inferred bounds for the impl.
|
||||||
generics: syn::Generics,
|
generics: syn::Generics,
|
||||||
@@ -105,18 +110,15 @@ impl Parameters {
|
|||||||
Ident::new("self", Span::call_site())
|
Ident::new("self", Span::call_site())
|
||||||
};
|
};
|
||||||
|
|
||||||
let this = match cont.attrs.remote() {
|
let this_type = this::this_type(cont);
|
||||||
Some(remote) => remote.clone(),
|
let this_value = this::this_value(cont);
|
||||||
None => cont.ident.clone().into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let is_packed = cont.attrs.is_packed();
|
let is_packed = cont.attrs.is_packed();
|
||||||
|
|
||||||
let generics = build_generics(cont);
|
let generics = build_generics(cont);
|
||||||
|
|
||||||
Parameters {
|
Parameters {
|
||||||
self_var,
|
self_var,
|
||||||
this,
|
this_type,
|
||||||
|
this_value,
|
||||||
generics,
|
generics,
|
||||||
is_remote,
|
is_remote,
|
||||||
is_packed,
|
is_packed,
|
||||||
@@ -126,7 +128,7 @@ impl Parameters {
|
|||||||
/// Type name to use in error messages and `&'static str` arguments to
|
/// Type name to use in error messages and `&'static str` arguments to
|
||||||
/// various Serializer methods.
|
/// various Serializer methods.
|
||||||
fn type_name(&self) -> String {
|
fn type_name(&self) -> String {
|
||||||
self.this.segments.last().unwrap().ident.to_string()
|
self.this_type.segments.last().unwrap().ident.to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,7 +429,7 @@ fn serialize_variant(
|
|||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let this = ¶ms.this;
|
let this_value = ¶ms.this_value;
|
||||||
let variant_ident = &variant.ident;
|
let variant_ident = &variant.ident;
|
||||||
|
|
||||||
if variant.attrs.skip_serializing() {
|
if variant.attrs.skip_serializing() {
|
||||||
@@ -445,32 +447,32 @@ fn serialize_variant(
|
|||||||
Style::Struct => quote!({ .. }),
|
Style::Struct => quote!({ .. }),
|
||||||
};
|
};
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident #fields_pat => #skipped_err,
|
#this_value::#variant_ident #fields_pat => #skipped_err,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// variant wasn't skipped
|
// variant wasn't skipped
|
||||||
let case = match variant.style {
|
let case = match variant.style {
|
||||||
Style::Unit => {
|
Style::Unit => {
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident
|
#this_value::#variant_ident
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Newtype => {
|
Style::Newtype => {
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident(ref __field0)
|
#this_value::#variant_ident(ref __field0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Tuple => {
|
Style::Tuple => {
|
||||||
let field_names = (0..variant.fields.len())
|
let field_names = (0..variant.fields.len())
|
||||||
.map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
|
.map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident(#(ref #field_names),*)
|
#this_value::#variant_ident(#(ref #field_names),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
Style::Struct => {
|
||||||
let members = variant.fields.iter().map(|f| &f.member);
|
let members = variant.fields.iter().map(|f| &f.member);
|
||||||
quote! {
|
quote! {
|
||||||
#this::#variant_ident { #(ref #members),* }
|
#this_value::#variant_ident { #(ref #members),* }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -640,7 +642,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
tag: &str,
|
tag: &str,
|
||||||
content: &str,
|
content: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let this = ¶ms.this;
|
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();
|
||||||
|
|
||||||
@@ -719,7 +721,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
quote_block! {
|
quote_block! {
|
||||||
struct __AdjacentlyTagged #wrapper_generics #where_clause {
|
struct __AdjacentlyTagged #wrapper_generics #where_clause {
|
||||||
data: (#(&'__a #fields_ty,)*),
|
data: (#(&'__a #fields_ty,)*),
|
||||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
|
||||||
@@ -741,7 +743,7 @@ fn serialize_adjacently_tagged_variant(
|
|||||||
try!(_serde::ser::SerializeStruct::serialize_field(
|
try!(_serde::ser::SerializeStruct::serialize_field(
|
||||||
&mut __struct, #content, &__AdjacentlyTagged {
|
&mut __struct, #content, &__AdjacentlyTagged {
|
||||||
data: (#(#fields_ident,)*),
|
data: (#(#fields_ident,)*),
|
||||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
}));
|
}));
|
||||||
_serde::ser::SerializeStruct::end(__struct)
|
_serde::ser::SerializeStruct::end(__struct)
|
||||||
}
|
}
|
||||||
@@ -866,8 +868,8 @@ enum StructVariant<'a> {
|
|||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct_variant<'a>(
|
fn serialize_struct_variant(
|
||||||
context: StructVariant<'a>,
|
context: StructVariant,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -950,8 +952,8 @@ fn serialize_struct_variant<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_struct_variant_with_flatten<'a>(
|
fn serialize_struct_variant_with_flatten(
|
||||||
context: StructVariant<'a>,
|
context: StructVariant,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &str,
|
||||||
@@ -971,7 +973,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
|||||||
variant_index,
|
variant_index,
|
||||||
variant_name,
|
variant_name,
|
||||||
} => {
|
} => {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let fields_ty = fields.iter().map(|f| &f.ty);
|
let fields_ty = fields.iter().map(|f| &f.ty);
|
||||||
let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();
|
let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();
|
||||||
|
|
||||||
@@ -982,7 +984,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
|||||||
quote_block! {
|
quote_block! {
|
||||||
struct __EnumFlatten #wrapper_generics #where_clause {
|
struct __EnumFlatten #wrapper_generics #where_clause {
|
||||||
data: (#(&'__a #fields_ty,)*),
|
data: (#(&'__a #fields_ty,)*),
|
||||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
|
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
|
||||||
@@ -1006,7 +1008,7 @@ fn serialize_struct_variant_with_flatten<'a>(
|
|||||||
#variant_name,
|
#variant_name,
|
||||||
&__EnumFlatten {
|
&__EnumFlatten {
|
||||||
data: (#(#members,)*),
|
data: (#(#members,)*),
|
||||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1192,7 +1194,7 @@ fn wrap_serialize_with(
|
|||||||
field_tys: &[&syn::Type],
|
field_tys: &[&syn::Type],
|
||||||
field_exprs: &[TokenStream],
|
field_exprs: &[TokenStream],
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let this = ¶ms.this;
|
let this_type = ¶ms.this_type;
|
||||||
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
|
||||||
|
|
||||||
let wrapper_generics = if field_exprs.is_empty() {
|
let wrapper_generics = if field_exprs.is_empty() {
|
||||||
@@ -1212,7 +1214,7 @@ fn wrap_serialize_with(
|
|||||||
quote!({
|
quote!({
|
||||||
struct __SerializeWith #wrapper_impl_generics #where_clause {
|
struct __SerializeWith #wrapper_impl_generics #where_clause {
|
||||||
values: (#(&'__a #field_tys, )*),
|
values: (#(&'__a #field_tys, )*),
|
||||||
phantom: _serde::__private::PhantomData<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
|
||||||
@@ -1226,7 +1228,7 @@ fn wrap_serialize_with(
|
|||||||
|
|
||||||
&__SerializeWith {
|
&__SerializeWith {
|
||||||
values: (#(#field_exprs, )*),
|
values: (#(#field_exprs, )*),
|
||||||
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
|
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use internals::ast::Container;
|
||||||
|
use syn::{Path, PathArguments, Token};
|
||||||
|
|
||||||
|
pub fn this_type(cont: &Container) -> Path {
|
||||||
|
if let Some(remote) = cont.attrs.remote() {
|
||||||
|
let mut this = remote.clone();
|
||||||
|
for segment in &mut this.segments {
|
||||||
|
if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
|
||||||
|
arguments.colon2_token = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
Path::from(cont.ident.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn this_value(cont: &Container) -> Path {
|
||||||
|
if let Some(remote) = cont.attrs.remote() {
|
||||||
|
let mut this = remote.clone();
|
||||||
|
for segment in &mut this.segments {
|
||||||
|
if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
|
||||||
|
if arguments.colon2_token.is_none() {
|
||||||
|
arguments.colon2_token = Some(Token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
Path::from(cont.ident.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
name = "serde_derive_internals"
|
name = "serde_derive_internals"
|
||||||
version = "0.26.0" # remember to update html_root_url
|
version = "0.26.0" # 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>"]
|
||||||
rust-version = "1.31"
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "AST representation used by Serde derive macros. Unstable."
|
description = "AST representation used by Serde derive macros. Unstable."
|
||||||
homepage = "https://serde.rs"
|
|
||||||
repository = "https://github.com/serde-rs/serde"
|
|
||||||
documentation = "https://docs.rs/serde_derive_internals"
|
documentation = "https://docs.rs/serde_derive_internals"
|
||||||
keywords = ["serde", "serialization"]
|
homepage = "https://serde.rs"
|
||||||
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
keywords = ["serde", "serialization"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/serde-rs/serde"
|
||||||
|
rust-version = "1.31"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
@@ -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 = "1.0.90", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
syn = { version = "1.0.104", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
clippy::doc_markdown,
|
clippy::doc_markdown,
|
||||||
clippy::enum_glob_use,
|
clippy::enum_glob_use,
|
||||||
clippy::items_after_statements,
|
clippy::items_after_statements,
|
||||||
clippy::let_underscore_drop,
|
|
||||||
clippy::manual_assert,
|
clippy::manual_assert,
|
||||||
clippy::match_same_arms,
|
clippy::match_same_arms,
|
||||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
|
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
|
||||||
|
|||||||
+11
-10
@@ -1,17 +1,18 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "1.0.137" # remember to update html_root_url
|
version = "1.0.149" # 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>"]
|
||||||
rust-version = "1.13"
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
|
||||||
homepage = "https://serde.rs"
|
|
||||||
repository = "https://github.com/serde-rs/serde"
|
|
||||||
documentation = "https://docs.serde.rs/serde_test/"
|
|
||||||
keywords = ["serde", "serialization"]
|
|
||||||
readme = "crates-io.md"
|
|
||||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
categories = ["development-tools::testing"]
|
||||||
|
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||||
|
documentation = "https://docs.serde.rs/serde_test/"
|
||||||
|
homepage = "https://serde.rs"
|
||||||
|
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||||
|
keywords = ["serde", "serialization", "testing", "dev-dependencies"]
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
readme = "crates-io.md"
|
||||||
|
repository = "https://github.com/serde-rs/serde"
|
||||||
|
rust-version = "1.13"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.60", path = "../serde" }
|
serde = { version = "1.0.60", path = "../serde" }
|
||||||
|
|||||||
+2
-2
@@ -13,8 +13,8 @@ fn main() {
|
|||||||
|
|
||||||
// #[track_caller] stabilized in Rust 1.46:
|
// #[track_caller] stabilized in Rust 1.46:
|
||||||
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
|
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
|
||||||
if minor >= 46 {
|
if minor < 46 {
|
||||||
println!("cargo:rustc-cfg=track_caller");
|
println!("cargo:rustc-cfg=no_track_caller");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use std::fmt::Debug;
|
|||||||
/// Token::StructEnd,
|
/// Token::StructEnd,
|
||||||
/// ]);
|
/// ]);
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(track_caller, track_caller)]
|
#[cfg_attr(not(no_track_caller), track_caller)]
|
||||||
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
||||||
where
|
where
|
||||||
T: Serialize + Deserialize<'de> + PartialEq + Debug,
|
T: Serialize + Deserialize<'de> + PartialEq + Debug,
|
||||||
@@ -59,7 +59,7 @@ where
|
|||||||
/// Token::StructEnd,
|
/// Token::StructEnd,
|
||||||
/// ]);
|
/// ]);
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(track_caller, track_caller)]
|
#[cfg_attr(not(no_track_caller), track_caller)]
|
||||||
pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
|
pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
@@ -112,7 +112,7 @@ where
|
|||||||
/// assert_ser_tokens_error(&example, expected, error);
|
/// assert_ser_tokens_error(&example, expected, error);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(track_caller, track_caller)]
|
#[cfg_attr(not(no_track_caller), track_caller)]
|
||||||
pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
|
pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
@@ -150,7 +150,7 @@ where
|
|||||||
/// Token::StructEnd,
|
/// Token::StructEnd,
|
||||||
/// ]);
|
/// ]);
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(track_caller, track_caller)]
|
#[cfg_attr(not(no_track_caller), track_caller)]
|
||||||
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
|
||||||
where
|
where
|
||||||
T: Deserialize<'de> + PartialEq + Debug,
|
T: Deserialize<'de> + PartialEq + Debug,
|
||||||
@@ -203,7 +203,7 @@ where
|
|||||||
/// "unknown field `x`, expected `a` or `b`",
|
/// "unknown field `x`, expected `a` or `b`",
|
||||||
/// );
|
/// );
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(track_caller, track_caller)]
|
#[cfg_attr(not(no_track_caller), track_caller)]
|
||||||
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
|
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
|
||||||
where
|
where
|
||||||
T: Deserialize<'de>,
|
T: Deserialize<'de>,
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.137")]
|
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.149")]
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||||
// Ignored clippy lints
|
// Ignored clippy lints
|
||||||
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
|
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
name = "serde_test_suite"
|
name = "serde_test_suite"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
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"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
build = "build.rs"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
expandtest = []
|
expandtest = []
|
||||||
@@ -24,4 +24,4 @@ rustversion = "1.0"
|
|||||||
serde = { path = "../serde", features = ["rc", "derive"] }
|
serde = { path = "../serde", features = ["rc", "derive"] }
|
||||||
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
|
||||||
serde_test = { path = "../serde_test" }
|
serde_test = { path = "../serde_test" }
|
||||||
trybuild = { version = "1.0.49", features = ["diff"] }
|
trybuild = { version = "1.0.66", features = ["diff"] }
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive_tests_no_std"
|
name = "serde_derive_tests_no_std"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
authors = ["David Tolnay <dtolnay@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
|
|||||||
@@ -1235,7 +1235,7 @@ fn serialize_variant_as_string<S>(f1: &str, f2: &u8, serializer: S) -> Result<S:
|
|||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
serializer.serialize_str(format!("{};{:?}", f1, f2).as_str())
|
serializer.serialize_str(format!("{f1};{f2:?}").as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error>
|
fn deserialize_string_as_variant<'de, D>(deserializer: D) -> Result<(String, u8), D::Error>
|
||||||
@@ -1244,22 +1244,17 @@ where
|
|||||||
{
|
{
|
||||||
let s = String::deserialize(deserializer)?;
|
let s = String::deserialize(deserializer)?;
|
||||||
let mut pieces = s.split(';');
|
let mut pieces = s.split(';');
|
||||||
let f1 = match pieces.next() {
|
let Some(f1) = pieces.next() else {
|
||||||
Some(x) => x,
|
return Err(de::Error::invalid_length(0, &"2"));
|
||||||
None => return Err(de::Error::invalid_length(0, &"2")),
|
|
||||||
};
|
};
|
||||||
let f2 = match pieces.next() {
|
let Some(f2) = pieces.next() else {
|
||||||
Some(x) => x,
|
return Err(de::Error::invalid_length(1, &"2"));
|
||||||
None => return Err(de::Error::invalid_length(1, &"2")),
|
|
||||||
};
|
};
|
||||||
let f2 = match f2.parse() {
|
let Ok(f2) = f2.parse() else {
|
||||||
Ok(n) => n,
|
return Err(de::Error::invalid_value(
|
||||||
Err(_) => {
|
Unexpected::Str(f2),
|
||||||
return Err(de::Error::invalid_value(
|
&"an 8-bit signed integer",
|
||||||
Unexpected::Str(f2),
|
));
|
||||||
&"an 8-bit signed integer",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok((f1.into(), f2))
|
Ok((f1.into(), f2))
|
||||||
}
|
}
|
||||||
@@ -2302,6 +2297,25 @@ fn test_internally_tagged_enum_containing_flatten() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_internally_tagged_enum_new_type_with_unit() {
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
#[serde(tag = "t")]
|
||||||
|
enum Data {
|
||||||
|
A(()),
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_tokens(
|
||||||
|
&Data::A(()),
|
||||||
|
&[
|
||||||
|
Token::Map { len: Some(1) },
|
||||||
|
Token::Str("t"),
|
||||||
|
Token::Str("A"),
|
||||||
|
Token::MapEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_adjacently_tagged_enum_containing_flatten() {
|
fn test_adjacently_tagged_enum_containing_flatten() {
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
clippy::empty_enum,
|
clippy::empty_enum,
|
||||||
clippy::manual_assert,
|
clippy::manual_assert,
|
||||||
clippy::needless_pass_by_value,
|
clippy::needless_pass_by_value,
|
||||||
|
clippy::uninlined_format_args,
|
||||||
clippy::unreadable_literal
|
clippy::unreadable_literal
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(feature = "unstable", feature(never_type))]
|
#![cfg_attr(feature = "unstable", feature(never_type))]
|
||||||
|
|||||||
@@ -74,6 +74,21 @@ mod remote {
|
|||||||
&self.b
|
&self.b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct StructGeneric<T> {
|
||||||
|
pub value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> StructGeneric<T> {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn get_value(&self) -> &T {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum EnumGeneric<T> {
|
||||||
|
Variant(T),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -104,6 +119,12 @@ struct Test {
|
|||||||
|
|
||||||
#[serde(with = "StructPubDef")]
|
#[serde(with = "StructPubDef")]
|
||||||
struct_pub: remote::StructPub,
|
struct_pub: remote::StructPub,
|
||||||
|
|
||||||
|
#[serde(with = "StructConcrete")]
|
||||||
|
struct_concrete: remote::StructGeneric<u8>,
|
||||||
|
|
||||||
|
#[serde(with = "EnumConcrete")]
|
||||||
|
enum_concrete: remote::EnumGeneric<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -157,6 +178,25 @@ struct StructPubDef {
|
|||||||
b: remote::Unit,
|
b: remote::Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(remote = "remote::StructGeneric")]
|
||||||
|
struct StructGenericWithGetterDef<T> {
|
||||||
|
#[serde(getter = "remote::StructGeneric::get_value")]
|
||||||
|
value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(remote = "remote::StructGeneric<u8>")]
|
||||||
|
struct StructConcrete {
|
||||||
|
value: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(remote = "remote::EnumGeneric<u8>")]
|
||||||
|
enum EnumConcrete {
|
||||||
|
Variant(u8),
|
||||||
|
}
|
||||||
|
|
||||||
impl From<PrimitivePrivDef> for remote::PrimitivePriv {
|
impl From<PrimitivePrivDef> for remote::PrimitivePriv {
|
||||||
fn from(def: PrimitivePrivDef) -> Self {
|
fn from(def: PrimitivePrivDef) -> Self {
|
||||||
remote::PrimitivePriv::new(def.0)
|
remote::PrimitivePriv::new(def.0)
|
||||||
@@ -180,3 +220,9 @@ impl From<StructPrivDef> for remote::StructPriv {
|
|||||||
remote::StructPriv::new(def.a, def.b)
|
remote::StructPriv::new(def.a, def.b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<StructGenericWithGetterDef<T>> for remote::StructGeneric<T> {
|
||||||
|
fn from(def: StructGenericWithGetterDef<T>) -> Self {
|
||||||
|
remote::StructGeneric { value: def.value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use std::sync::atomic::{
|
|||||||
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
|
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
|
||||||
AtomicUsize,
|
AtomicUsize,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Weak as ArcWeak};
|
use std::sync::{Arc, Mutex, RwLock, Weak as ArcWeak};
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@@ -800,17 +800,14 @@ fn test_never_result() {
|
|||||||
#[test]
|
#[test]
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn test_cannot_serialize_paths() {
|
fn test_cannot_serialize_paths() {
|
||||||
let path = unsafe { str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") };
|
use std::ffi::OsStr;
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
assert_ser_tokens_error(
|
assert_ser_tokens_error(
|
||||||
&Path::new(path),
|
&Path::new(OsStr::from_bytes(b"Hello \xF0\x90\x80World")),
|
||||||
&[],
|
&[],
|
||||||
"path contains invalid UTF-8 characters",
|
"path contains invalid UTF-8 characters",
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut path_buf = PathBuf::new();
|
|
||||||
path_buf.push(path);
|
|
||||||
|
|
||||||
assert_ser_tokens_error(&path_buf, &[], "path contains invalid UTF-8 characters");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -850,3 +847,39 @@ fn test_integer128() {
|
|||||||
|
|
||||||
assert_ser_tokens_error(&1u128, &[], "u128 is not supported");
|
assert_ser_tokens_error(&1u128, &[], "u128 is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_refcell_dst() {
|
||||||
|
assert_ser_tokens(
|
||||||
|
&RefCell::new([true]) as &RefCell<[bool]>,
|
||||||
|
&[
|
||||||
|
Token::Seq { len: Some(1) },
|
||||||
|
Token::Bool(true),
|
||||||
|
Token::SeqEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mutex_dst() {
|
||||||
|
assert_ser_tokens(
|
||||||
|
&Mutex::new([true]) as &Mutex<[bool]>,
|
||||||
|
&[
|
||||||
|
Token::Seq { len: Some(1) },
|
||||||
|
Token::Bool(true),
|
||||||
|
Token::SeqEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rwlock_dst() {
|
||||||
|
assert_ser_tokens(
|
||||||
|
&RwLock::new([true]) as &RwLock<[bool]>,
|
||||||
|
&[
|
||||||
|
Token::Seq { len: Some(1) },
|
||||||
|
Token::Bool(true),
|
||||||
|
Token::SeqEnd,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
mod remote {
|
||||||
|
pub struct Struct<T, U> {
|
||||||
|
pub t: T,
|
||||||
|
pub u: U,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(remote = "remote::StructGeneric<u8>")]
|
||||||
|
struct StructDef<U> {
|
||||||
|
t: u8,
|
||||||
|
u: U,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
error: remove generic parameters from this path
|
||||||
|
--> tests/ui/remote/double_generic.rs:11:18
|
||||||
|
|
|
||||||
|
11 | #[serde(remote = "remote::StructGeneric<u8>")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> tests/ui/remote/wrong_ser.rs:9:10
|
--> tests/ui/remote/wrong_ser.rs:9:10
|
||||||
|
|
|
|
||||||
9 | #[derive(Serialize)]
|
9 | #[derive(Serialize)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
| expected `u8`, found `u16`
|
| expected `u8`, found `u16`
|
||||||
| arguments to this function are incorrect
|
| arguments to this function are incorrect
|
||||||
|
|
|
|
||||||
= note: expected reference `&u8`
|
= note: expected reference `&u8`
|
||||||
found reference `&u16`
|
found reference `&u16`
|
||||||
note: function defined here
|
note: function defined here
|
||||||
--> $WORKSPACE/serde/src/private/ser.rs
|
--> $WORKSPACE/serde/src/private/ser.rs
|
||||||
|
|
|
|
||||||
| pub fn constrain<T: ?Sized>(t: &T) -> &T {
|
| pub fn constrain<T: ?Sized>(t: &T) -> &T {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
= note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|||||||
Reference in New Issue
Block a user