Compare commits

..

2 Commits

Author SHA1 Message Date
David Tolnay af31449cb1 Run test suite on wa-serde-derive 2022-07-01 17:56:18 -07:00
David Tolnay 1afae183b0 Compile serde_derive to wasm 2022-07-01 17:55:51 -07:00
54 changed files with 408 additions and 748 deletions
+1 -17
View File
@@ -5,9 +5,6 @@ on:
pull_request: pull_request:
schedule: [cron: "40 1 * * *"] schedule: [cron: "40 1 * * *"]
permissions:
contents: read
env: env:
RUSTFLAGS: -Dwarnings RUSTFLAGS: -Dwarnings
@@ -15,7 +12,6 @@ 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
@@ -28,7 +24,6 @@ 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
@@ -41,7 +36,6 @@ 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
@@ -59,7 +53,6 @@ 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
@@ -78,13 +71,12 @@ 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 yearmo=$(date +%Y%m) >> $GITHUB_OUTPUT run: echo ::set-output name=yearmo::$(date +%Y%m)
- uses: actions/cache@v1 - uses: actions/cache@v1
with: with:
path: ~/.cargo/registry/index path: ~/.cargo/registry/index
@@ -100,7 +92,6 @@ 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
@@ -116,7 +107,6 @@ 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
@@ -130,7 +120,6 @@ 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
@@ -141,7 +130,6 @@ 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
@@ -150,7 +138,6 @@ 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
@@ -174,7 +161,6 @@ 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
@@ -188,7 +174,6 @@ 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
@@ -203,7 +188,6 @@ 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
-1
View File
@@ -1,7 +1,6 @@
[workspace] [workspace]
members = [ members = [
"serde", "serde",
"serde_derive",
"serde_derive_internals", "serde_derive_internals",
"serde_test", "serde_test",
"test_suite", "test_suite",
+1 -1
View File
@@ -1,6 +1,6 @@
# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31] # Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31]
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master [Build Status]: https://img.shields.io/github/workflow/status/serde-rs/serde/CI/master
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster [actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
[Latest Version]: https://img.shields.io/crates/v/serde.svg [Latest Version]: https://img.shields.io/crates/v/serde.svg
[crates.io]: https://crates.io/crates/serde [crates.io]: https://crates.io/crates/serde
+12 -12
View File
@@ -1,21 +1,21 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.151" # remember to update html_root_url and serde_derive dependency version = "1.0.137" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
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" 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"
[dependencies] [dependencies]
serde_derive = { version = "=1.0.151", optional = true, path = "../serde_derive" } serde_derive = { version = "=1.0.137", 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" }
+16 -22
View File
@@ -6,8 +6,6 @@ use std::str::{self, FromStr};
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script. // these cfgs other than by executing our build script.
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() { let minor = match rustc_minor_version() {
Some(minor) => minor, Some(minor) => minor,
None => return, None => return,
@@ -91,28 +89,24 @@ 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");
} }
// Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60. // Whitelist of archs that support std::sync::atomic module. Ideally we
if minor < 60 { // would use #[cfg(target_has_atomic = "...")] but it is not stable yet.
println!("cargo:rustc-cfg=no_target_has_atomic"); // Instead this is based on rustc's compiler/rustc_target/src/spec/*.rs.
// Allowlist of archs that support std::sync::atomic module. This is let has_atomic64 = target.starts_with("x86_64")
// based on rustc's compiler/rustc_target/src/spec/*.rs. || target.starts_with("i686")
let has_atomic64 = target.starts_with("x86_64") || target.starts_with("aarch64")
|| target.starts_with("i686") || target.starts_with("powerpc64")
|| target.starts_with("aarch64") || target.starts_with("sparc64")
|| target.starts_with("powerpc64") || target.starts_with("mips64el")
|| target.starts_with("sparc64") || target.starts_with("riscv64");
|| target.starts_with("mips64el") let has_atomic32 = has_atomic64 || emscripten;
|| target.starts_with("riscv64"); if minor < 34 || !has_atomic64 {
let has_atomic32 = has_atomic64 || emscripten; println!("cargo:rustc-cfg=no_std_atomic64");
if minor < 34 || !has_atomic64 { }
println!("cargo:rustc-cfg=no_std_atomic64"); if minor < 34 || !has_atomic32 {
} println!("cargo:rustc-cfg=no_std_atomic");
if minor < 34 || !has_atomic32 {
println!("cargo:rustc-cfg=no_std_atomic");
}
} }
} }
+1 -1
View File
@@ -1,7 +1,7 @@
use lib::fmt::{self, Write}; use lib::fmt::{self, Write};
use lib::str; use lib::str;
pub(super) struct Buf<'a> { pub struct Buf<'a> {
bytes: &'a mut [u8], bytes: &'a mut [u8],
offset: usize, offset: usize,
} }
+1 -1
View File
@@ -228,7 +228,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
where where
A: EnumAccess<'de>, A: EnumAccess<'de>,
{ {
try!(data.variant::<IgnoredAny>()).1.newtype_variant() data.variant::<IgnoredAny>()?.1.newtype_variant()
} }
} }
+22 -30
View File
@@ -733,7 +733,7 @@ impl<'de> Deserialize<'de> for CString {
macro_rules! forwarded_impl { macro_rules! forwarded_impl {
( (
$(#[doc = $doc:tt])* $(#[doc = $doc:tt])*
($($id:ident),*), $ty:ty, $func:expr ( $($id: ident),* ), $ty: ty, $func: expr
) => { ) => {
$(#[doc = $doc])* $(#[doc = $doc])*
impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty { impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
@@ -860,7 +860,7 @@ impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! seq_impl { macro_rules! seq_impl {
( (
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)*>, $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident, $access:ident,
$clear:expr, $clear:expr,
$with_capacity:expr, $with_capacity:expr,
@@ -1353,7 +1353,7 @@ tuple_impls! {
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl { macro_rules! map_impl {
( (
$ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)*>, $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident, $access:ident,
$with_capacity:expr $with_capacity:expr
) => { ) => {
@@ -1440,15 +1440,15 @@ macro_rules! parse_ip_impl {
#[cfg(feature = "std")] #[cfg(feature = "std")]
macro_rules! variant_identifier { macro_rules! variant_identifier {
( (
$name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
$expecting_message:expr, $expecting_message: expr,
$variants_name:ident $variants_name: ident
) => { ) => {
enum $name_kind { enum $name_kind {
$($variant),* $( $variant ),*
} }
static $variants_name: &'static [&'static str] = &[$(stringify!($variant)),*]; static $variants_name: &'static [&'static str] = &[ $( stringify!($variant) ),*];
impl<'de> Deserialize<'de> for $name_kind { impl<'de> Deserialize<'de> for $name_kind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -1515,12 +1515,12 @@ macro_rules! variant_identifier {
#[cfg(feature = "std")] #[cfg(feature = "std")]
macro_rules! deserialize_enum { macro_rules! deserialize_enum {
( (
$name:ident $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*) $name: ident $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
$expecting_message:expr, $expecting_message: expr,
$deserializer:expr $deserializer: expr
) => { ) => {
variant_identifier! { variant_identifier!{
$name_kind ($($variant; $bytes; $index),*) $name_kind ( $($variant; $bytes; $index),* )
$expecting_message, $expecting_message,
VARIANTS VARIANTS
} }
@@ -2268,14 +2268,14 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let (start, end) = try!(deserializer.deserialize_struct( let (start, end) = 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) = try!(deserializer.deserialize_struct( let (start, end) = 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))
} }
} }
@@ -2662,9 +2662,8 @@ where
#[cfg(all(feature = "std", not(no_std_atomic)))] #[cfg(all(feature = "std", not(no_std_atomic)))]
macro_rules! atomic_impl { macro_rules! atomic_impl {
($($ty:ident $size:expr)*) => { ($($ty:ident)*) => {
$( $(
#[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
impl<'de> Deserialize<'de> for $ty { impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -2679,21 +2678,14 @@ macro_rules! atomic_impl {
#[cfg(all(feature = "std", not(no_std_atomic)))] #[cfg(all(feature = "std", not(no_std_atomic)))]
atomic_impl! { atomic_impl! {
AtomicBool "8" AtomicBool
AtomicI8 "8" AtomicI8 AtomicI16 AtomicI32 AtomicIsize
AtomicI16 "16" AtomicU8 AtomicU16 AtomicU32 AtomicUsize
AtomicI32 "32"
AtomicIsize "ptr"
AtomicU8 "8"
AtomicU16 "16"
AtomicU32 "32"
AtomicUsize "ptr"
} }
#[cfg(all(feature = "std", not(no_std_atomic64)))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
atomic_impl! { atomic_impl! {
AtomicI64 "64" AtomicI64 AtomicU64
AtomicU64 "64"
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
+12 -17
View File
@@ -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 [`postcard`]. //! example [`serde_json`], [`serde_yaml`] and [`bincode`].
//! //!
//! 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
//! [`postcard`]: https://github.com/jamesmunns/postcard //! [`bincode`]: https://github.com/bincode-org/bincode
//! [`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 = try!(Deserialize::deserialize(deserializer)); *place = Deserialize::deserialize(deserializer)?;
Ok(()) Ok(())
} }
} }
@@ -708,11 +708,6 @@ 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()? {
@@ -862,10 +857,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_any` method. Self-describing data formats like JSON are /// 1. The `deserialize` method. Self-describing data formats like JSON are able
/// able to look at the serialized data and tell what it represents. For /// to look at the serialized data and tell what it represents. For example
/// example the JSON deserializer may see an opening curly brace (`{`) and /// the JSON deserializer may see an opening curly brace (`{`) and know that
/// know that it is seeing a map. If the data format supports /// 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
@@ -874,7 +869,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
/// Postcard need to be told what is in the input in order to deserialize it. /// Bincode 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
@@ -884,7 +879,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 Postcard and many /// deserialize from self-describing formats only, ruling out Bincode and many
/// others. /// others.
/// ///
/// [Serde data model]: https://serde.rs/data-model.html /// [Serde data model]: https://serde.rs/data-model.html
@@ -915,7 +910,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 Postcard and /// deserialize from self-describing formats only, ruling out Bincode 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
@@ -1156,7 +1151,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 Postcard will prefer the /// human-readable one and binary formats like Bincode will prefer the
/// compact one. /// compact one.
/// ///
/// ```edition2018 /// ```edition2018
@@ -1560,7 +1555,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 Postcard data containing bytes can be deserialized with zero /// example Bincode 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`.
+9 -88
View File
@@ -128,7 +128,9 @@ where
type Deserializer = UnitDeserializer<E>; type Deserializer = UnitDeserializer<E>;
fn into_deserializer(self) -> UnitDeserializer<E> { fn into_deserializer(self) -> UnitDeserializer<E> {
UnitDeserializer::new() UnitDeserializer {
marker: PhantomData,
}
} }
} }
@@ -139,15 +141,6 @@ 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,
@@ -243,15 +236,8 @@ 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: value, value: self,
marker: PhantomData, marker: PhantomData,
} }
} }
@@ -322,15 +308,8 @@ 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: value, value: self,
marker: PhantomData, marker: PhantomData,
} }
} }
@@ -411,15 +390,8 @@ 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: value, value: self,
marker: PhantomData, marker: PhantomData,
} }
} }
@@ -589,16 +561,8 @@ 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: value, value: self,
marker: PhantomData, marker: PhantomData,
} }
} }
@@ -692,16 +656,8 @@ 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: value, value: self,
marker: PhantomData, marker: PhantomData,
} }
} }
@@ -1501,7 +1457,7 @@ where
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
match try!(self.map.next_key_seed(seed)) { match 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")),
} }
@@ -1510,41 +1466,6 @@ 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::*;
+13 -37
View File
@@ -31,7 +31,8 @@
//! 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.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format. //! - [Bincode], a 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
@@ -44,6 +45,7 @@
//! - [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)*
@@ -57,16 +59,17 @@
//! and from DynamoDB. //! and from DynamoDB.
//! //!
//! [JSON]: https://github.com/serde-rs/json //! [JSON]: https://github.com/serde-rs/json
//! [Postcard]: https://github.com/jamesmunns/postcard //! [Bincode]: https://github.com/bincode-org/bincode
//! [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://docs.rs/toml //! [TOML]: https://github.com/alexcrichton/toml-rs
//! [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://docs.rs/apache-avro //! [Avro]: https://github.com/flavray/avro-rs
//! [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
@@ -81,14 +84,14 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.151")] #![doc(html_root_url = "https://docs.rs/serde/1.0.137")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue: // discussion of these features please refer to this issue:
// //
// https://github.com/serde-rs/serde/issues/812 // https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))] #![cfg_attr(feature = "unstable", feature(never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)] #![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
// Ignored clippy and clippy_pedantic lints // Ignored clippy and clippy_pedantic lints
@@ -117,9 +120,8 @@
// correctly used // correctly used
derive_partial_eq_without_eq, derive_partial_eq_without_eq,
enum_glob_use, enum_glob_use,
explicit_auto_deref, let_underscore_drop,
map_err_ignore, map_err_ignore,
new_without_default,
result_unit_err, result_unit_err,
wildcard_imports, wildcard_imports,
// not practical // not practical
@@ -236,44 +238,18 @@ mod lib {
#[cfg(not(no_range_inclusive))] #[cfg(not(no_range_inclusive))]
pub use self::core::ops::RangeInclusive; pub use self::core::ops::RangeInclusive;
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))] #[cfg(all(feature = "std", not(no_std_atomic)))]
pub use std::sync::atomic::{ pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
AtomicUsize, Ordering, AtomicUsize, Ordering,
}; };
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
pub use std::sync::atomic::{AtomicI64, AtomicU64}; pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(all(feature = "std", not(no_target_has_atomic)))]
pub use std::sync::atomic::Ordering;
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "8"))]
pub use std::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "16"))]
pub use std::sync::atomic::{AtomicI16, AtomicU16};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "32"))]
pub use std::sync::atomic::{AtomicI32, AtomicU32};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "64"))]
pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
pub use std::sync::atomic::{AtomicIsize, AtomicUsize};
#[cfg(any(feature = "std", not(no_core_duration)))] #[cfg(any(feature = "std", not(no_core_duration)))]
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]
@@ -303,7 +279,7 @@ use self::__private as private;
#[path = "de/seed.rs"] #[path = "de/seed.rs"]
mod seed; mod seed;
#[cfg(not(any(feature = "std", feature = "unstable")))] #[cfg(not(feature = "std"))]
mod std_error; mod std_error;
// Re-export #[derive(Serialize, Deserialize)]. // Re-export #[derive(Serialize, Deserialize)].
+7 -18
View File
@@ -1262,17 +1262,6 @@ 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)),
} }
} }
@@ -1810,7 +1799,7 @@ mod content {
V: Visitor<'de>, V: Visitor<'de>,
E: de::Error, E: de::Error,
{ {
let map = content.iter().map(|(k, v)| { let map = content.iter().map(|&(ref k, ref v)| {
( (
ContentRefDeserializer::new(k), ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v), ContentRefDeserializer::new(v),
@@ -2107,7 +2096,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 (variant, value) = match iter.next() { let &(ref variant, ref value) = match iter.next() {
Some(v) => v, Some(v) => v,
None => { None => {
return Err(de::Error::invalid_value( return Err(de::Error::invalid_value(
@@ -2254,7 +2243,7 @@ mod content {
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
match self.value { match self.value {
Some(Content::Seq(v)) => { Some(&Content::Seq(ref 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(
@@ -2277,10 +2266,10 @@ mod content {
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
match self.value { match self.value {
Some(Content::Map(v)) => { Some(&Content::Map(ref v)) => {
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
} }
Some(Content::Seq(v)) => { Some(&Content::Seq(ref 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(
@@ -2403,7 +2392,7 @@ mod content {
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some(&(ref key, ref value)) => {
self.value = Some(value); self.value = Some(value);
seed.deserialize(ContentRefDeserializer::new(key)).map(Some) seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
} }
@@ -2708,7 +2697,7 @@ where
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! forward_to_deserialize_other { macro_rules! forward_to_deserialize_other {
($($func:ident ($($arg:ty),*))*) => { ($($func:ident ( $($arg:ty),* ))*) => {
$( $(
fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error> fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error>
where where
+4 -4
View File
@@ -51,6 +51,7 @@ 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,
@@ -69,6 +70,7 @@ 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"),
@@ -182,9 +184,7 @@ where
} }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(1))); Err(self.bad_type(Unsupported::Unit))
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 (k, v) in entries { for &(ref k, ref v) in entries {
try!(map.serialize_entry(k, v)); try!(map.serialize_entry(k, v));
} }
map.end() map.end()
+19 -66
View File
@@ -182,27 +182,9 @@ where
} }
} }
#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))] #[cfg(any(feature = "std", feature = "alloc"))]
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)*>
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 {
($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)*>
where where
T: Serialize $(+ $tbound1 $(+ $tbound2)*)*, T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
@@ -365,28 +347,9 @@ tuple_impls! {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))] #[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl { macro_rules! map_impl {
($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => { ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where
K: Serialize,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_map(self)
}
}
}
}
#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
macro_rules! map_impl {
($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*> impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where where
K: Serialize $(+ $kbound1 $(+ $kbound2)*)*, K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
@@ -502,7 +465,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
macro_rules! nonzero_integers { macro_rules! nonzero_integers {
($($T:ident,)+) => { ( $( $T: ident, )+ ) => {
$( $(
#[cfg(not(no_num_nonzero))] #[cfg(not(no_num_nonzero))]
impl Serialize for num::$T { impl Serialize for num::$T {
@@ -559,7 +522,7 @@ where
} }
} }
impl<T: ?Sized> Serialize for RefCell<T> impl<T> Serialize for RefCell<T>
where where
T: Serialize, T: Serialize,
{ {
@@ -575,7 +538,7 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<T: ?Sized> Serialize for Mutex<T> impl<T> Serialize for Mutex<T>
where where
T: Serialize, T: Serialize,
{ {
@@ -591,7 +554,7 @@ where
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl<T: ?Sized> Serialize for RwLock<T> impl<T> Serialize for RwLock<T>
where where
T: Serialize, T: Serialize,
{ {
@@ -651,10 +614,9 @@ impl Serialize for SystemTime {
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let duration_since_epoch = match self.duration_since(UNIX_EPOCH) { let duration_since_epoch = self
Ok(duration_since_epoch) => duration_since_epoch, .duration_since(UNIX_EPOCH)
Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")), .map_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()));
@@ -773,9 +735,8 @@ 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;
} }
// Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8 // We've only written ASCII bytes to the buffer, so it is valid UTF-8
let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) }; serializer.serialize_str(unsafe { str::from_utf8_unchecked(&buf[..written]) })
serializer.serialize_str(buf)
} else { } else {
self.octets().serialize(serializer) self.octets().serialize(serializer)
} }
@@ -947,16 +908,15 @@ where
#[cfg(all(feature = "std", not(no_std_atomic)))] #[cfg(all(feature = "std", not(no_std_atomic)))]
macro_rules! atomic_impl { macro_rules! atomic_impl {
($($ty:ident $size:expr)*) => { ($($ty:ident)*) => {
$( $(
#[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
impl Serialize for $ty { impl Serialize for $ty {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
// 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::Relaxed).serialize(serializer) self.load(Ordering::SeqCst).serialize(serializer)
} }
} }
)* )*
@@ -965,19 +925,12 @@ macro_rules! atomic_impl {
#[cfg(all(feature = "std", not(no_std_atomic)))] #[cfg(all(feature = "std", not(no_std_atomic)))]
atomic_impl! { atomic_impl! {
AtomicBool "8" AtomicBool
AtomicI8 "8" AtomicI8 AtomicI16 AtomicI32 AtomicIsize
AtomicI16 "16" AtomicU8 AtomicU16 AtomicU32 AtomicUsize
AtomicI32 "32"
AtomicIsize "ptr"
AtomicU8 "8"
AtomicU16 "16"
AtomicU32 "32"
AtomicUsize "ptr"
} }
#[cfg(all(feature = "std", not(no_std_atomic64)))] #[cfg(all(feature = "std", not(no_std_atomic64)))]
atomic_impl! { atomic_impl! {
AtomicI64 "64" AtomicI64 AtomicU64
AtomicU64 "64"
} }
+5 -8
View File
@@ -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 [`postcard`]. //! example [`serde_json`], [`serde_yaml`] and [`bincode`].
//! //!
//! 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
//! [`postcard`]: https://github.com/jamesmunns/postcard //! [`bincode`]: https://github.com/bincode-org/bincode
//! [`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
@@ -115,13 +115,10 @@ mod impossible;
pub use self::impossible::Impossible; pub use self::impossible::Impossible;
#[cfg(all(feature = "unstable", not(feature = "std")))]
#[doc(inline)]
pub use core::error::Error as StdError;
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[doc(no_inline)] #[doc(no_inline)]
pub use std::error::Error as StdError; pub use std::error::Error as StdError;
#[cfg(not(any(feature = "std", feature = "unstable")))] #[cfg(not(feature = "std"))]
#[doc(no_inline)] #[doc(no_inline)]
pub use std_error::Error as StdError; pub use std_error::Error as StdError;
@@ -317,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 Postcard. This is not a requirement of the `Serializer` trait, and /// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example /// 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
@@ -1426,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 Postcard will prefer the /// human-readable one and binary formats like Bincode will prefer the
/// compact one. /// compact one.
/// ///
/// ```edition2018 /// ```edition2018
+16 -13
View File
@@ -1,33 +1,36 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.151" # remember to update html_root_url version = "1.0.137" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
documentation = "https://serde.rs/derive.html"
homepage = "https://serde.rs"
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" rust-version = "1.31"
license = "MIT OR Apache-2.0"
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"
keywords = ["serde", "serialization", "no_std"]
readme = "crates-io.md"
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[features] [features]
default = [] default = []
deserialize_in_place = [] deserialize_in_place = []
[lib] [lib]
name = "serde_derive" crate-type = ["cdylib"]
proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "1.0.104" syn = "1.0.90"
[dev-dependencies] [dev-dependencies]
serde = { version = "1.0", path = "../serde" } serde = { version = "1.0", path = "../serde" }
[package.metadata.docs.rs] [package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"] targets = ["x86_64-unknown-linux-gnu"]
[workspace]
[patch.crates-io]
proc-macro2 = { git = "https://github.com/dtolnay/watt" }
+4 -6
View File
@@ -6,8 +6,6 @@ use std::str;
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script. // these cfgs other than by executing our build script.
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() { let minor = match rustc_minor_version() {
Some(minor) => minor, Some(minor) => minor,
None => return, None => return,
@@ -15,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=no_underscore_consts"); println!("cargo:rustc-cfg=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=no_ptr_addr_of"); println!("cargo:rustc-cfg=ptr_addr_of");
} }
} }
+88 -98
View File
@@ -10,7 +10,6 @@ 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;
@@ -112,13 +111,9 @@ 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 (does not include generic parameters) or `some::remote::Path` for /// types or `some::remote::Ident` for remote types. Does not include
/// remote types. /// generic parameters.
this_type: syn::Path, this: 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,
@@ -138,8 +133,10 @@ 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_type = this::this_type(cont); let this = match cont.attrs.remote() {
let this_value = this::this_value(cont); Some(remote) => remote.clone(),
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();
@@ -147,8 +144,7 @@ impl Parameters {
Parameters { Parameters {
local, local,
this_type, this,
this_value,
generics, generics,
borrowed, borrowed,
has_getter, has_getter,
@@ -159,7 +155,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_type.segments.last().unwrap().ident.to_string() self.this.segments.last().unwrap().ident.to_string()
} }
} }
@@ -362,7 +358,7 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
Data::Enum(_) => unreachable!(), Data::Enum(_) => unreachable!(),
}; };
let this_value = &params.this_value; let this = &params.this;
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() {
@@ -390,7 +386,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_value { #(#assign),* }) |__transparent| #this { #(#assign),* })
} }
} }
@@ -411,8 +407,7 @@ 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_type = &params.this_type; let this = &params.this;
let this_value = &params.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());
@@ -422,7 +417,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; type Value = #this;
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)
@@ -433,7 +428,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_value) _serde::__private::Ok(#this)
} }
} }
@@ -448,8 +443,7 @@ fn deserialize_tuple(
cattrs: &attr::Container, cattrs: &attr::Container,
deserializer: Option<TokenStream>, deserializer: Option<TokenStream>,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this = &params.this;
let this_value = &params.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();
@@ -463,7 +457,7 @@ fn deserialize_tuple(
let local = &params.local; let local = &params.local;
quote!(#local) quote!(#local)
} else { } else {
quote!(#this_value) quote!(#this)
}; };
let is_enum = variant_ident.is_some(); let is_enum = variant_ident.is_some();
@@ -491,7 +485,7 @@ fn deserialize_tuple(
let visitor_expr = quote! { let visitor_expr = quote! {
__Visitor { __Visitor {
marker: _serde::__private::PhantomData::<#this_type #ty_generics>, marker: _serde::__private::PhantomData::<#this #ty_generics>,
lifetime: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData,
} }
}; };
@@ -516,12 +510,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #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)
@@ -550,7 +544,7 @@ fn deserialize_tuple_in_place(
cattrs: &attr::Container, cattrs: &attr::Container,
deserializer: Option<TokenStream>, deserializer: Option<TokenStream>,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this = &params.this;
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();
@@ -606,7 +600,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_type #ty_generics, place: &#place_life mut #this #ty_generics,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
} }
@@ -711,10 +705,9 @@ fn deserialize_seq(
}; };
if params.has_getter { if params.has_getter {
let this_type = &params.this_type; let this = &params.this;
let (_, ty_generics, _) = params.generics.split_for_impl();
result = quote! { result = quote! {
_serde::__private::Into::<#this_type #ty_generics>::into(#result) _serde::__private::Into::<#this>::into(#result)
}; };
} }
@@ -808,14 +801,14 @@ fn deserialize_seq_in_place(
} }
}); });
let this_type = &params.this_type; let this = &params.this;
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_type #ty_generics = _serde::__private::Default::default(); let __default: #this #ty_generics = _serde::__private::Default::default();
)), )),
attr::Default::Path(path) => Some(quote!( attr::Default::Path(path) => Some(quote!(
let __default: #this_type #ty_generics = #path(); let __default: #this #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
@@ -856,10 +849,9 @@ 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_type = &params.this_type; let this = &params.this;
let (_, ty_generics, _) = params.generics.split_for_impl();
result = quote! { result = quote! {
_serde::__private::Into::<#this_type #ty_generics>::into(#result) _serde::__private::Into::<#this>::into(#result)
}; };
} }
@@ -909,8 +901,7 @@ fn deserialize_struct(
) -> Fragment { ) -> Fragment {
let is_enum = variant_ident.is_some(); let is_enum = variant_ident.is_some();
let this_type = &params.this_type; let this = &params.this;
let this_value = &params.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();
@@ -922,7 +913,7 @@ fn deserialize_struct(
let local = &params.local; let local = &params.local;
quote!(#local) quote!(#local)
} else { } else {
quote!(#this_value) quote!(#this)
}; };
let type_path = match variant_ident { let type_path = match variant_ident {
@@ -950,7 +941,7 @@ fn deserialize_struct(
let visitor_expr = quote! { let visitor_expr = quote! {
__Visitor { __Visitor {
marker: _serde::__private::PhantomData::<#this_type #ty_generics>, marker: _serde::__private::PhantomData::<#this #ty_generics>,
lifetime: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData,
} }
}; };
@@ -1002,7 +993,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_type #ty_generics; type Value = #this #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
@@ -1020,12 +1011,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #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)
@@ -1066,7 +1057,7 @@ fn deserialize_struct_in_place(
return None; return None;
} }
let this_type = &params.this_type; let this = &params.this;
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();
@@ -1132,7 +1123,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_type #ty_generics, place: &#place_life mut #this #ty_generics,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
} }
@@ -1221,7 +1212,7 @@ fn deserialize_externally_tagged_enum(
variants: &[Variant], variants: &[Variant],
cattrs: &attr::Container, cattrs: &attr::Container,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this = &params.this;
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();
@@ -1275,12 +1266,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #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)
@@ -1301,7 +1292,7 @@ fn deserialize_externally_tagged_enum(
#type_name, #type_name,
VARIANTS, VARIANTS,
__Visitor { __Visitor {
marker: _serde::__private::PhantomData::<#this_type #ty_generics>, marker: _serde::__private::PhantomData::<#this #ty_generics>,
lifetime: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData,
}, },
) )
@@ -1363,8 +1354,7 @@ fn deserialize_adjacently_tagged_enum(
tag: &str, tag: &str,
content: &str, content: &str,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this = &params.this;
let this_value = &params.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();
@@ -1425,13 +1415,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_value::#variant_ident) _serde::__private::Ok(#this::#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_value::#variant_ident) #func(#content).map(#this::#variant_ident)
} }
} }
_ => { _ => {
@@ -1523,12 +1513,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #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
@@ -1541,12 +1531,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #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)
@@ -1648,7 +1638,7 @@ fn deserialize_adjacently_tagged_enum(
#type_name, #type_name,
FIELDS, FIELDS,
__Visitor { __Visitor {
marker: _serde::__private::PhantomData::<#this_type #ty_generics>, marker: _serde::__private::PhantomData::<#this #ty_generics>,
lifetime: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData,
}, },
) )
@@ -1717,10 +1707,10 @@ fn deserialize_externally_tagged_variant(
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
let this_value = &params.this_value; let this = &params.this;
quote_block! { quote_block! {
try!(_serde::de::VariantAccess::unit_variant(__variant)); try!(_serde::de::VariantAccess::unit_variant(__variant));
_serde::__private::Ok(#this_value::#variant_ident) _serde::__private::Ok(#this::#variant_ident)
} }
} }
Style::Newtype => deserialize_externally_tagged_newtype_variant( Style::Newtype => deserialize_externally_tagged_newtype_variant(
@@ -1759,7 +1749,7 @@ fn deserialize_internally_tagged_variant(
match effective_style(variant) { match effective_style(variant) {
Style::Unit => { Style::Unit => {
let this_value = &params.this_value; let this = &params.this;
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| {
@@ -1768,7 +1758,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_value::#variant_ident #default) _serde::__private::Ok(#this::#variant_ident #default)
} }
} }
Style::Newtype => deserialize_untagged_newtype_variant( Style::Newtype => deserialize_untagged_newtype_variant(
@@ -1806,7 +1796,7 @@ fn deserialize_untagged_variant(
match effective_style(variant) { match effective_style(variant) {
Style::Unit => { Style::Unit => {
let this_value = &params.this_value; let this = &params.this;
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| {
@@ -1818,7 +1808,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_value::#variant_ident #default), _serde::__private::Ok(()) => _serde::__private::Ok(#this::#variant_ident #default),
_serde::__private::Err(__err) => _serde::__private::Err(__err), _serde::__private::Err(__err) => _serde::__private::Err(__err),
} }
} }
@@ -1853,13 +1843,14 @@ fn deserialize_externally_tagged_newtype_variant(
field: &Field, field: &Field,
cattrs: &attr::Container, cattrs: &attr::Container,
) -> Fragment { ) -> Fragment {
let this_value = &params.this_value; let this = &params.this;
if field.attrs.skip_deserializing() { if field.attrs.skip_deserializing() {
let this = &params.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_value::#variant_ident(#default)) _serde::__private::Ok(#this::#variant_ident(#default))
}; };
} }
@@ -1870,7 +1861,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_value::#variant_ident) _serde::__private::Result::map(#func(__variant), #this::#variant_ident)
} }
} }
Some(path) => { Some(path) => {
@@ -1879,7 +1870,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_value::#variant_ident(__wrapper.value)) |__wrapper| #this::#variant_ident(__wrapper.value))
} }
} }
} }
@@ -1891,20 +1882,20 @@ fn deserialize_untagged_newtype_variant(
field: &Field, field: &Field,
deserializer: &TokenStream, deserializer: &TokenStream,
) -> Fragment { ) -> Fragment {
let this_value = &params.this_value; let this = &params.this;
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_value::#variant_ident) _serde::__private::Result::map(#func(#deserializer), #this::#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_value::#variant_ident) _serde::__private::Result::map(__value, #this::#variant_ident)
} }
} }
} }
@@ -1916,7 +1907,7 @@ fn deserialize_generated_identifier(
is_variant: bool, is_variant: bool,
other_idx: Option<usize>, other_idx: Option<usize>,
) -> Fragment { ) -> Fragment {
let this_value = quote!(__Field); let this = 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() {
@@ -1936,7 +1927,7 @@ fn deserialize_generated_identifier(
}; };
let visitor_impl = Stmts(deserialize_identifier( let visitor_impl = Stmts(deserialize_identifier(
&this_value, &this,
fields, fields,
is_variant, is_variant,
fallthrough, fallthrough,
@@ -1991,8 +1982,8 @@ fn deserialize_custom_identifier(
attr::Identifier::No => unreachable!(), attr::Identifier::No => unreachable!(),
}; };
let this_type = params.this_type.to_token_stream(); let this = &params.this;
let this_value = params.this_value.to_token_stream(); let this = quote!(#this);
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;
@@ -2001,7 +1992,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_value::#last_ident)); let fallthrough = quote!(_serde::__private::Ok(#this::#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];
@@ -2011,7 +2002,7 @@ fn deserialize_custom_identifier(
_serde::Deserialize::deserialize( _serde::Deserialize::deserialize(
_serde::__private::de::IdentifierDeserializer::from(#value) _serde::__private::de::IdentifierDeserializer::from(#value)
), ),
#this_value::#last_ident) #this::#last_ident)
} }
}; };
( (
@@ -2059,7 +2050,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_value, &this,
&names_idents, &names_idents,
is_variant, is_variant,
fallthrough, fallthrough,
@@ -2072,18 +2063,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_type #ty_generics>, marker: _serde::__private::PhantomData<#this #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_type #ty_generics; type Value = #this #ty_generics;
#visitor_impl #visitor_impl
} }
let __visitor = __FieldVisitor { let __visitor = __FieldVisitor {
marker: _serde::__private::PhantomData::<#this_type #ty_generics>, marker: _serde::__private::PhantomData::<#this #ty_generics>,
lifetime: _serde::__private::PhantomData, lifetime: _serde::__private::PhantomData,
}; };
_serde::Deserializer::deserialize_identifier(__deserializer, __visitor) _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
@@ -2091,7 +2082,7 @@ fn deserialize_custom_identifier(
} }
fn deserialize_identifier( fn deserialize_identifier(
this_value: &TokenStream, this: &TokenStream,
fields: &[(String, Ident, Vec<String>)], fields: &[(String, Ident, Vec<String>)],
is_variant: bool, is_variant: bool,
fallthrough: Option<TokenStream>, fallthrough: Option<TokenStream>,
@@ -2112,11 +2103,11 @@ fn deserialize_identifier(
let constructors: &Vec<_> = &flat_fields let constructors: &Vec<_> = &flat_fields
.iter() .iter()
.map(|(_, ident)| quote!(#this_value::#ident)) .map(|(_, ident)| quote!(#this::#ident))
.collect(); .collect();
let main_constructors: &Vec<_> = &fields let main_constructors: &Vec<_> = &fields
.iter() .iter()
.map(|(_, ident, _)| quote!(#this_value::#ident)) .map(|(_, ident, _)| quote!(#this::#ident))
.collect(); .collect();
let expecting = expecting.unwrap_or(if is_variant { let expecting = expecting.unwrap_or(if is_variant {
@@ -2630,10 +2621,9 @@ 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_type = &params.this_type; let this = &params.this;
let (_, ty_generics, _) = params.generics.split_for_impl();
result = quote! { result = quote! {
_serde::__private::Into::<#this_type #ty_generics>::into(#result) _serde::__private::Into::<#this>::into(#result)
}; };
} }
@@ -2813,15 +2803,15 @@ fn deserialize_map_in_place(
} }
}); });
let this_type = &params.this_type; let this = &params.this;
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_type #ty_generics = _serde::__private::Default::default(); let __default: #this #ty_generics = _serde::__private::Default::default();
)), )),
attr::Default::Path(path) => Some(quote!( attr::Default::Path(path) => Some(quote!(
let __default: #this_type #ty_generics = #path(); let __default: #this #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
@@ -2854,7 +2844,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_type = &params.this_type; let this = &params.this;
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();
@@ -2862,7 +2852,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_type #ty_generics>, phantom: _serde::__private::PhantomData<#this #ty_generics>,
lifetime: _serde::__private::PhantomData<&#delife ()>, lifetime: _serde::__private::PhantomData<&#delife ()>,
} }
@@ -2913,7 +2903,7 @@ fn unwrap_to_variant_closure(
variant: &Variant, variant: &Variant,
with_wrapper: bool, with_wrapper: bool,
) -> TokenStream { ) -> TokenStream {
let this_value = &params.this_value; let this = &params.this;
let variant_ident = &variant.ident; let variant_ident = &variant.ident;
let (arg, wrapper) = if with_wrapper { let (arg, wrapper) = if with_wrapper {
@@ -2934,23 +2924,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_value::#variant_ident { #member: #wrapper } |#arg| #this::#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_value::#variant_ident { #(#members: #wrapper.#field_access),* } |#arg| #this::#variant_ident { #(#members: #wrapper.#field_access),* }
} }
} }
Style::Tuple => quote! { Style::Tuple => quote! {
|#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*) |#arg| #this::#variant_ident(#(#wrapper.#field_access),*)
}, },
Style::Newtype => quote! { Style::Newtype => quote! {
|#arg| #this_value::#variant_ident(#wrapper) |#arg| #this::#variant_ident(#wrapper)
}, },
Style::Unit => quote! { Style::Unit => quote! {
|#arg| #this_value::#variant_ident |#arg| #this::#variant_ident
}, },
} }
} }
+3 -3
View File
@@ -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!(no_underscore_consts) { let dummy_const = if cfg!(underscore_consts) {
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
} else {
format_ident!("_") format_ident!("_")
} else {
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
}; };
let use_serde = match serde_path { let use_serde = match serde_path {
-23
View File
@@ -6,7 +6,6 @@ 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);
@@ -17,28 +16,6 @@ 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) {
+20 -17
View File
@@ -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.151")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.137")]
#![allow(unknown_lints, bare_trait_objects)] #![allow(unknown_lints, bare_trait_objects)]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
@@ -43,6 +43,7 @@
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,
@@ -67,12 +68,11 @@ extern crate quote;
#[macro_use] #[macro_use]
extern crate syn; extern crate syn;
extern crate proc_macro;
extern crate proc_macro2; extern crate proc_macro2;
mod internals; mod internals;
use proc_macro::TokenStream; use proc_macro2::TokenStream;
use syn::DeriveInput; use syn::DeriveInput;
#[macro_use] #[macro_use]
@@ -84,26 +84,29 @@ 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))] #[no_mangle]
pub fn derive_serialize(input: TokenStream) -> TokenStream { pub extern "C" fn derive_serialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput); let mut input: DeriveInput = match syn::parse2(input) {
ser::expand_derive_serialize(&mut input) Ok(input) => input,
.unwrap_or_else(to_compile_errors) Err(err) => return err.to_compile_error(),
.into() };
ser::expand_derive_serialize(&mut input).unwrap_or_else(to_compile_errors)
} }
#[proc_macro_derive(Deserialize, attributes(serde))] #[no_mangle]
pub fn derive_deserialize(input: TokenStream) -> TokenStream { pub extern "C" fn derive_deserialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput); let mut input: DeriveInput = match syn::parse2(input) {
de::expand_derive_deserialize(&mut input) Ok(input) => input,
.unwrap_or_else(to_compile_errors) Err(err) => return err.to_compile_error(),
.into() };
de::expand_derive_deserialize(&mut input).unwrap_or_else(to_compile_errors)
} }
fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream { fn to_compile_errors(errors: Vec<syn::Error>) -> TokenStream {
let compile_errors = errors.iter().map(syn::Error::to_compile_error); let compile_errors = errors.iter().map(syn::Error::to_compile_error);
quote!(#(#compile_errors)*) quote!(#(#compile_errors)*)
} }
+2 -2
View File
@@ -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(not(no_ptr_addr_of))] #[cfg(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(no_ptr_addr_of)] #[cfg(not(ptr_addr_of))]
{ {
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i)); let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+30 -32
View File
@@ -8,7 +8,6 @@ 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,
@@ -83,13 +82,9 @@ 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 (does not include generic parameters) or `some::remote::Path` for /// types or `some::remote::Ident` for remote types. Does not include
/// remote types. /// generic parameters.
this_type: syn::Path, this: 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,
@@ -110,15 +105,18 @@ impl Parameters {
Ident::new("self", Span::call_site()) Ident::new("self", Span::call_site())
}; };
let this_type = this::this_type(cont); let this = match cont.attrs.remote() {
let this_value = this::this_value(cont); Some(remote) => remote.clone(),
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_type, this,
this_value,
generics, generics,
is_remote, is_remote,
is_packed, is_packed,
@@ -128,7 +126,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_type.segments.last().unwrap().ident.to_string() self.this.segments.last().unwrap().ident.to_string()
} }
} }
@@ -429,7 +427,7 @@ fn serialize_variant(
variant_index: u32, variant_index: u32,
cattrs: &attr::Container, cattrs: &attr::Container,
) -> TokenStream { ) -> TokenStream {
let this_value = &params.this_value; let this = &params.this;
let variant_ident = &variant.ident; let variant_ident = &variant.ident;
if variant.attrs.skip_serializing() { if variant.attrs.skip_serializing() {
@@ -447,32 +445,32 @@ fn serialize_variant(
Style::Struct => quote!({ .. }), Style::Struct => quote!({ .. }),
}; };
quote! { quote! {
#this_value::#variant_ident #fields_pat => #skipped_err, #this::#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_value::#variant_ident #this::#variant_ident
} }
} }
Style::Newtype => { Style::Newtype => {
quote! { quote! {
#this_value::#variant_ident(ref __field0) #this::#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_value::#variant_ident(#(ref #field_names),*) #this::#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_value::#variant_ident { #(ref #members),* } #this::#variant_ident { #(ref #members),* }
} }
} }
}; };
@@ -642,7 +640,7 @@ fn serialize_adjacently_tagged_variant(
tag: &str, tag: &str,
content: &str, content: &str,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this = &params.this;
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();
@@ -721,7 +719,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_type #ty_generics>, phantom: _serde::__private::PhantomData<#this #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 {
@@ -743,7 +741,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_type #ty_generics>, phantom: _serde::__private::PhantomData::<#this #ty_generics>,
})); }));
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
} }
@@ -868,8 +866,8 @@ enum StructVariant<'a> {
Untagged, Untagged,
} }
fn serialize_struct_variant( fn serialize_struct_variant<'a>(
context: StructVariant, context: StructVariant<'a>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
name: &str, name: &str,
@@ -952,8 +950,8 @@ fn serialize_struct_variant(
} }
} }
fn serialize_struct_variant_with_flatten( fn serialize_struct_variant_with_flatten<'a>(
context: StructVariant, context: StructVariant<'a>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
name: &str, name: &str,
@@ -973,7 +971,7 @@ fn serialize_struct_variant_with_flatten(
variant_index, variant_index,
variant_name, variant_name,
} => { } => {
let this_type = &params.this_type; let this = &params.this;
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<_>>();
@@ -984,7 +982,7 @@ fn serialize_struct_variant_with_flatten(
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_type #ty_generics>, phantom: _serde::__private::PhantomData<#this #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 {
@@ -1008,7 +1006,7 @@ fn serialize_struct_variant_with_flatten(
#variant_name, #variant_name,
&__EnumFlatten { &__EnumFlatten {
data: (#(#members,)*), data: (#(#members,)*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, phantom: _serde::__private::PhantomData::<#this #ty_generics>,
}) })
} }
} }
@@ -1194,7 +1192,7 @@ fn wrap_serialize_with(
field_tys: &[&syn::Type], field_tys: &[&syn::Type],
field_exprs: &[TokenStream], field_exprs: &[TokenStream],
) -> TokenStream { ) -> TokenStream {
let this_type = &params.this_type; let this = &params.this;
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() {
@@ -1214,7 +1212,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_type #ty_generics>, phantom: _serde::__private::PhantomData<#this #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 {
@@ -1228,7 +1226,7 @@ fn wrap_serialize_with(
&__SerializeWith { &__SerializeWith {
values: (#(#field_exprs, )*), values: (#(#field_exprs, )*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>, phantom: _serde::__private::PhantomData::<#this #ty_generics>,
} }
}) })
} }
-32
View File
@@ -1,32 +0,0 @@
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![::](arguments.lt_token.span));
}
}
}
this
} else {
Path::from(cont.ident.clone())
}
}
+8 -8
View File
@@ -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>"]
description = "AST representation used by Serde derive macros. Unstable."
documentation = "https://docs.rs/serde_derive_internals"
homepage = "https://serde.rs"
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" rust-version = "1.31"
license = "MIT OR Apache-2.0"
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"
keywords = ["serde", "serialization"]
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
[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.104", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] } syn = { version = "1.0.90", 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"]
-3
View File
@@ -1,9 +1,6 @@
use std::path::Path; use std::path::Path;
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/mod.rs");
// Sometimes on Windows the git checkout does not correctly wire up the // Sometimes on Windows the git checkout does not correctly wire up the
// symlink from serde_derive_internals/src to serde_derive/src/internals. // symlink from serde_derive_internals/src to serde_derive/src/internals.
// When this happens we'll just build based on relative paths within the git // When this happens we'll just build based on relative paths within the git
+1
View File
@@ -22,6 +22,7 @@
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
+10 -11
View File
@@ -1,18 +1,17 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.151" # remember to update html_root_url version = "1.0.137" # 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>"]
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" 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"
[dependencies] [dependencies]
serde = { version = "1.0.60", path = "../serde" } serde = { version = "1.0.60", path = "../serde" }
+2 -4
View File
@@ -6,8 +6,6 @@ use std::str::{self, FromStr};
// opening a GitHub issue if your build environment requires some way to enable // opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script. // these cfgs other than by executing our build script.
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() { let minor = match rustc_minor_version() {
Some(minor) => minor, Some(minor) => minor,
None => return, None => return,
@@ -15,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=no_track_caller"); println!("cargo:rustc-cfg=track_caller");
} }
} }
+5 -5
View File
@@ -28,7 +28,7 @@ use std::fmt::Debug;
/// Token::StructEnd, /// Token::StructEnd,
/// ]); /// ]);
/// ``` /// ```
#[cfg_attr(not(no_track_caller), track_caller)] #[cfg_attr(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(not(no_track_caller), track_caller)] #[cfg_attr(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(not(no_track_caller), track_caller)] #[cfg_attr(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(not(no_track_caller), track_caller)] #[cfg_attr(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(not(no_track_caller), track_caller)] #[cfg_attr(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>,
+1 -1
View File
@@ -144,7 +144,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.151")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.137")]
#![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))]
+6 -4
View File
@@ -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 = []
@@ -21,7 +21,9 @@ fnv = "1.0"
macrotest = "=1.0.9" macrotest = "=1.0.9"
prettyplease = "=0.1.14" prettyplease = "=0.1.14"
rustversion = "1.0" rustversion = "1.0"
serde = { path = "../serde", features = ["rc", "derive"] } serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] } wa-serde-derive = { path = "../wa-serde-derive" }
serde_test = { path = "../serde_test" } serde_test = { path = "../serde_test" }
trybuild = { version = "1.0.66", features = ["diff"] } trybuild = { version = "1.0.49", features = ["diff"] }
[workspace]
-2
View File
@@ -19,8 +19,6 @@ fn has_cargo_expand() -> bool {
} }
fn main() { fn main() {
println!("cargo:rerun-if-changed=build.rs");
if cfg!(feature = "expandtest") && has_cargo_expand() { if cfg!(feature = "expandtest") && has_cargo_expand() {
println!("cargo:rustc-cfg=expandtest"); println!("cargo:rustc-cfg=expandtest");
} }
-1
View File
@@ -1,7 +1,6 @@
[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
+2
View File
@@ -1,3 +1,5 @@
#![cfg(any())]
#[cfg_attr(target_os = "emscripten", ignore)] #[cfg_attr(target_os = "emscripten", ignore)]
#[rustversion::attr(not(nightly), ignore)] #[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)] #[cfg_attr(miri, ignore)]
+16 -29
View File
@@ -11,6 +11,7 @@
use serde::de::{self, MapAccess, Unexpected, Visitor}; use serde::de::{self, MapAccess, Unexpected, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_derive::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::convert::TryFrom; use std::convert::TryFrom;
@@ -1235,7 +1236,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,17 +1245,22 @@ where
{ {
let s = String::deserialize(deserializer)?; let s = String::deserialize(deserializer)?;
let mut pieces = s.split(';'); let mut pieces = s.split(';');
let Some(f1) = pieces.next() else { let f1 = match pieces.next() {
return Err(de::Error::invalid_length(0, &"2")); Some(x) => x,
None => return Err(de::Error::invalid_length(0, &"2")),
}; };
let Some(f2) = pieces.next() else { let f2 = match pieces.next() {
return Err(de::Error::invalid_length(1, &"2")); Some(x) => x,
None => return Err(de::Error::invalid_length(1, &"2")),
}; };
let Ok(f2) = f2.parse() else { let f2 = match f2.parse() {
return Err(de::Error::invalid_value( Ok(n) => n,
Unexpected::Str(f2), Err(_) => {
&"an 8-bit signed integer", return Err(de::Error::invalid_value(
)); Unexpected::Str(f2),
&"an 8-bit signed integer",
));
}
}; };
Ok((f1.into(), f2)) Ok((f1.into(), f2))
} }
@@ -2297,25 +2303,6 @@ 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)]
+1
View File
@@ -5,6 +5,7 @@
)] )]
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, assert_de_tokens_error, Token}; use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
use std::borrow::Cow; use std::borrow::Cow;
+1 -1
View File
@@ -5,7 +5,6 @@
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))]
@@ -35,6 +34,7 @@ use std::sync::atomic::{AtomicI64, AtomicU64};
use fnv::FnvHasher; use fnv::FnvHasher;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, Configure, Token}; use serde_test::{assert_de_tokens, Configure, Token};
#[macro_use] #[macro_use]
+1
View File
@@ -7,6 +7,7 @@
use serde::de::IntoDeserializer; use serde::de::IntoDeserializer;
use serde::Deserialize; use serde::Deserialize;
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens_error, Token}; use serde_test::{assert_de_tokens_error, Token};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
+1
View File
@@ -2,6 +2,7 @@
// successfully when there are a variety of generics and non-(de)serializable // successfully when there are a variety of generics and non-(de)serializable
// types involved. // types involved.
#![cfg(any())]
#![deny(warnings)] #![deny(warnings)]
#![allow( #![allow(
unknown_lints, unknown_lints,
+1 -1
View File
@@ -2,7 +2,7 @@
#![allow(clippy::derive_partial_eq_without_eq)] #![allow(clippy::derive_partial_eq_without_eq)]
use serde::Deserialize; use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, Token}; use serde_test::{assert_de_tokens, Token};
#[test] #[test]
+1
View File
@@ -5,6 +5,7 @@ use serde::de::{
DeserializeSeed, EnumAccess, IgnoredAny, IntoDeserializer, VariantAccess, Visitor, DeserializeSeed, EnumAccess, IgnoredAny, IntoDeserializer, VariantAccess, Visitor,
}; };
use serde::{forward_to_deserialize_any, Deserialize, Deserializer}; use serde::{forward_to_deserialize_any, Deserialize, Deserializer};
use serde_derive::Deserialize;
#[derive(PartialEq, Debug, Deserialize)] #[derive(PartialEq, Debug, Deserialize)]
enum Target { enum Target {
+1 -1
View File
@@ -8,7 +8,7 @@
mod bytes; mod bytes;
use serde::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use serde_test::{ use serde_test::{
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token, assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Token,
}; };
+1 -47
View File
@@ -1,6 +1,6 @@
#![allow(clippy::redundant_field_names)] #![allow(clippy::redundant_field_names)]
use serde::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
mod remote { mod remote {
pub struct Unit; pub struct Unit;
@@ -74,21 +74,6 @@ 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)]
@@ -119,12 +104,6 @@ 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)]
@@ -178,25 +157,6 @@ 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)
@@ -220,9 +180,3 @@ 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 }
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
#![allow(clippy::used_underscore_binding)] #![allow(clippy::used_underscore_binding)]
use serde::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
#[test] #[test]
fn test_self() { fn test_self() {
+9 -42
View File
@@ -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, Mutex, RwLock, Weak as ArcWeak}; use std::sync::{Arc, Weak as ArcWeak};
use std::time::{Duration, UNIX_EPOCH}; use std::time::{Duration, UNIX_EPOCH};
#[cfg(unix)] #[cfg(unix)]
@@ -22,7 +22,7 @@ use std::str;
use std::sync::atomic::{AtomicI64, AtomicU64}; use std::sync::atomic::{AtomicI64, AtomicU64};
use fnv::FnvHasher; use fnv::FnvHasher;
use serde::Serialize; use serde_derive::Serialize;
use serde_test::{assert_ser_tokens, assert_ser_tokens_error, Configure, Token}; use serde_test::{assert_ser_tokens, assert_ser_tokens_error, Configure, Token};
#[macro_use] #[macro_use]
@@ -800,14 +800,17 @@ fn test_never_result() {
#[test] #[test]
#[cfg(unix)] #[cfg(unix)]
fn test_cannot_serialize_paths() { fn test_cannot_serialize_paths() {
use std::ffi::OsStr; let path = unsafe { str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") };
use std::os::unix::ffi::OsStrExt;
assert_ser_tokens_error( assert_ser_tokens_error(
&Path::new(OsStr::from_bytes(b"Hello \xF0\x90\x80World")), &Path::new(path),
&[], &[],
"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]
@@ -847,39 +850,3 @@ 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,
],
);
}
+1 -1
View File
@@ -2,7 +2,7 @@
#[test] #[test]
fn test_gen_custom_serde() { fn test_gen_custom_serde() {
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
#[serde(crate = "fake_serde")] #[serde(crate = "fake_serde")]
struct Foo; struct Foo;
+1
View File
@@ -3,6 +3,7 @@
use serde::de::value::{self, MapAccessDeserializer}; use serde::de::value::{self, MapAccessDeserializer};
use serde::de::{IntoDeserializer, MapAccess, Visitor}; use serde::de::{IntoDeserializer, MapAccess, Visitor};
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, Token}; use serde_test::{assert_de_tokens, Token};
use std::fmt; use std::fmt;
@@ -1,17 +0,0 @@
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() {}
@@ -1,5 +0,0 @@
error: remove generic parameters from this path
--> tests/ui/remote/double_generic.rs:11:18
|
11 | #[serde(remote = "remote::StructGeneric<u8>")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+15 -15
View File
@@ -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)
+1
View File
@@ -0,0 +1 @@
*.wasm
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "wa-serde-derive"
version = "0.1.137"
authors = ["David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "serde_derive compiled to wasm"
repository = "https://github.com/dtolnay/watt"
include = ["src"]
[lib]
name = "serde_derive"
proc-macro = true
[dependencies]
watt = "0.4"
[workspace]
+18
View File
@@ -0,0 +1,18 @@
extern crate proc_macro;
extern crate watt;
use proc_macro::TokenStream;
use watt::WasmMacro;
static MACRO: WasmMacro = WasmMacro::new(WASM);
static WASM: &[u8] = include_bytes!("serde_derive.wasm");
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
MACRO.proc_macro_derive("derive_serialize", input)
}
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
MACRO.proc_macro_derive("derive_deserialize", input)
}