Compare commits

...

29 Commits

Author SHA1 Message Date
David Tolnay 1799547846 Release 1.0.226 2025-09-20 16:34:44 -07:00
David Tolnay 2dbeefb11b Merge pull request #2935 from Mingun/dedupe-adj-enums
Remove code duplication when deriving Deserialize for adjacently tagged enums
2025-09-20 16:33:32 -07:00
David Tolnay 8a3c29ff19 Merge pull request #2986 from dtolnay/didnotwork
Remove "did not work" comment from test suite
2025-09-20 12:30:39 -07:00
David Tolnay defc24d361 Remove "did not work" comment from test suite 2025-09-20 12:23:01 -07:00
Oli Scherer 2316610760 Merge pull request #2929 from Mingun/flatten-enum-tests
Add more tests for flatten enums to increase test coverage
2025-09-18 13:15:10 +00:00
Mingun c09e2bd690 Add tests for flatten unit variant in adjacently tagged (tag + content) enums 2025-09-17 23:53:07 +05:00
Mingun fe7dcc4cd8 Test all possible orders of map entries for enum-flatten-in-struct representations 2025-09-17 23:51:30 +05:00
Mingun a20e66e131 Check serialization in flatten::enum_::internally_tagged::unit_enum_with_unknown_fields 2025-09-17 23:50:00 +05:00
Mingun 1c1a5d95cd Reorder struct_ and newtype tests of adjacently_tagged enums to match order in Enum 2025-09-17 23:48:23 +05:00
David Tolnay ee3c2372fb Opt in to generate-macro-expansion when building on docs.rs 2025-09-16 16:29:21 -07:00
Mingun bfb020d975 Use variant name for field instead of field 2025-09-17 00:09:51 +05:00
Mingun 6805bba308 Inline variables that used only once 2025-09-17 00:09:14 +05:00
Mingun 2659b94a62 Create deserializer only when needed 2025-09-17 00:08:07 +05:00
Mingun c451415d9f Do not duplicate variant deserialization code 2025-09-17 00:07:00 +05:00
Mingun 553a9ff15f Document functions that are entry points for generating bodies of different deserialization forms 2025-09-17 00:05:53 +05:00
David Tolnay 6f5eb7d207 Merge pull request #2983 from Mingun/fix-test-instructions
Fix instructions for testing contributions
2025-09-16 09:24:04 -07:00
Mingun 55615e8f8e Fix instructions for testing contributions
Since separation of serde_core from serde, all doctests lives in serde_core project,
which also does not have the `derive` feature. Following the old instructions does not
run any tests.
2025-09-16 21:15:49 +05:00
David Tolnay 1d7899d671 Release 1.0.225 2025-09-15 20:43:08 -07:00
David Tolnay 97168d3a24 Touch up PR 2879 2025-09-15 20:38:57 -07:00
David Tolnay 373b11dda7 Merge pull request 2879 from rcrisanti/fix/silence-deprecation-warnings-derive 2025-09-15 20:26:40 -07:00
David Tolnay 69072f2423 Merge pull request 2931 from Mingun/unify-serde-access 2025-09-15 13:22:24 -07:00
David Tolnay 5b37e8a531 Merge pull request #2980 from dtolnay/private
Use differently named __private module per patch release
2025-09-15 13:20:54 -07:00
Mingun b47f4dfa96 Unify access to the serde namespace
In other places `_serde` name is used to access the `serde` crate, so use it there
2025-09-16 00:36:12 +05:00
David Tolnay cbe98a9888 Use differently named __private module per patch release 2025-09-15 09:53:14 -07:00
David Tolnay 957996f5fb Make all use of __private go through interpolation 2025-09-15 09:48:26 -07:00
David Tolnay 169988206a Release 1.0.224 2025-09-15 08:46:21 -07:00
David Tolnay 840f6ec9b8 Merge pull request #2979 from dtolnay/private
Mark every trait impl for a private type with do_not_recommend
2025-09-15 08:45:06 -07:00
David Tolnay bf9ebea392 Mark every trait impl for a private type with do_not_recommend 2025-09-14 19:47:36 -07:00
Ryan Crisanti ae38b27aee add #[allow(deprecated)] to derive implementations
Allow deprecated in the `Serialize`/`Deserialize`
derive implementations. This allows you to
deprecate structs, enums, struct fields, or enum
variants and not get compiler warnings/errors
about use of deprecated thing. We only do this
if `#[deprecated]` or `#[allow(deprecated)]` exist
on the root object or the variants of the root
object (if it is an enum).

Resolves #2195
2025-05-30 15:01:14 -04:00
28 changed files with 1309 additions and 433 deletions
+3 -3
View File
@@ -27,11 +27,11 @@ pull request with your changes. If anything does not pass, typically it will be
easier to iterate and fix it locally than waiting for the CI servers to run
tests for you.
##### In the [`serde`] directory
##### In the [`serde_core`] directory
```sh
# Test all the example code in Serde documentation
cargo test --features derive
cargo test
```
##### In the [`test_suite`] directory
@@ -43,7 +43,7 @@ cargo +nightly test --features unstable
Note that this test suite currently only supports running on a nightly compiler.
[`serde`]: https://github.com/serde-rs/serde/tree/master/serde
[`serde_core`]: https://github.com/serde-rs/serde/tree/master/serde_core
[`test_suite`]: https://github.com/serde-rs/serde/tree/master/test_suite
## Conduct
+3 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.223"
version = "1.0.226"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -15,7 +15,7 @@ repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
[dependencies]
serde_core = { version = "=1.0.223", path = "../serde_core", default-features = false, features = ["result"] }
serde_core = { version = "=1.0.226", path = "../serde_core", default-features = false, features = ["result"] }
serde_derive = { version = "1", optional = true, path = "../serde_derive" }
[package.metadata.playground]
@@ -26,6 +26,7 @@ features = ["derive", "rc", "unstable"]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = [
"--generate-link-to-definition",
"--generate-macro-expansion",
"--extern-html-root-url=core=https://doc.rust-lang.org",
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
"--extern-html-root-url=std=https://doc.rust-lang.org",
+23
View File
@@ -1,19 +1,36 @@
use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use std::str;
const PRIVATE: &str = "\
#[doc(hidden)]
pub mod __private$$ {
#[doc(hidden)]
pub use crate::private::*;
}
use serde_core::__private$$ as serde_core_private;
";
// The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let patch_version = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
let module = PRIVATE.replace("$$", &patch_version);
fs::write(out_dir.join("private.rs"), module).unwrap();
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
if minor >= 77 {
println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
println!("cargo:rustc-check-cfg=cfg(no_serde_derive)");
}
@@ -21,6 +38,12 @@ fn main() {
if minor < 61 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for the `#[diagnostic]` tool attribute namespace
// https://blog.rust-lang.org/2024/05/02/Rust-1.78.0.html#diagnostic-attributes
if minor < 78 {
println!("cargo:rustc-cfg=no_diagnostic_namespace");
}
}
fn rustc_minor_version() -> Option<u32> {
+4 -3
View File
@@ -95,7 +95,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.223")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.226")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
@@ -239,8 +239,9 @@ mod integer128;
// Used by generated code and doc tests. Not public API.
#[doc(hidden)]
#[path = "private/mod.rs"]
pub mod __private;
mod private;
include!(concat!(env!("OUT_DIR"), "/private.rs"));
// Re-export #[derive(Serialize, Deserialize)].
//
+55 -3
View File
@@ -17,7 +17,7 @@ pub use self::content::{
UntaggedUnitVisitor,
};
pub use serde_core::__private::InPlaceSeed;
pub use crate::serde_core_private::InPlaceSeed;
/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
@@ -28,6 +28,7 @@ where
{
struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for MissingFieldDeserializer<E>
where
E: Error,
@@ -67,6 +68,7 @@ where
{
struct CowStrVisitor;
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a> Visitor<'a> for CowStrVisitor {
type Value = Cow<'a, str>;
@@ -140,6 +142,7 @@ where
{
struct CowBytesVisitor;
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a> Visitor<'a> for CowBytesVisitor {
type Value = Cow<'a, [u8]>;
@@ -213,8 +216,8 @@ mod content {
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
};
use serde_core::__private::size_hint;
pub use serde_core::__private::Content;
use crate::serde_core_private::size_hint;
pub use crate::serde_core_private::Content;
pub fn content_as_str<'a, 'de>(content: &'a Content<'de>) -> Option<&'a str> {
match *content {
@@ -294,6 +297,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> DeserializeSeed<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
@@ -305,6 +309,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> Visitor<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
@@ -530,6 +535,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> DeserializeSeed<'de> for TagOrContentVisitor<'de> {
type Value = TagOrContent<'de>;
@@ -543,6 +549,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> Visitor<'de> for TagOrContentVisitor<'de> {
type Value = TagOrContent<'de>;
@@ -824,6 +831,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, T> Visitor<'de> for TaggedContentVisitor<T>
where
T: Deserialize<'de>,
@@ -894,6 +902,7 @@ mod content {
pub content: &'static str,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor {
type Value = TagOrContentField;
@@ -905,6 +914,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> Visitor<'de> for TagOrContentFieldVisitor {
type Value = TagOrContentField;
@@ -971,6 +981,7 @@ mod content {
pub content: &'static str,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> DeserializeSeed<'de> for TagContentOtherFieldVisitor {
type Value = TagContentOtherField;
@@ -982,6 +993,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de> Visitor<'de> for TagContentOtherFieldVisitor {
type Value = TagContentOtherField;
@@ -1104,6 +1116,7 @@ mod content {
/// Used when deserializing an internally tagged enum because the content
/// will be used exactly once.
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where
E: de::Error,
@@ -1523,6 +1536,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for SeqDeserializer<'de, E>
where
E: de::Error,
@@ -1545,6 +1559,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> SeqAccess<'de> for SeqDeserializer<'de, E>
where
E: de::Error,
@@ -1571,6 +1586,7 @@ mod content {
struct ExpectedInSeq(usize);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Expected for ExpectedInSeq {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.0 == 1 {
@@ -1630,6 +1646,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for MapDeserializer<'de, E>
where
E: de::Error,
@@ -1669,6 +1686,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> MapAccess<'de> for MapDeserializer<'de, E>
where
E: de::Error,
@@ -1723,6 +1741,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> SeqAccess<'de> for MapDeserializer<'de, E>
where
E: de::Error,
@@ -1749,6 +1768,7 @@ mod content {
struct PairDeserializer<'de, E>(Content<'de>, Content<'de>, PhantomData<E>);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for PairDeserializer<'de, E>
where
E: de::Error,
@@ -1800,6 +1820,7 @@ mod content {
struct PairVisitor<'de, E>(Option<Content<'de>>, Option<Content<'de>>, PhantomData<E>);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> SeqAccess<'de> for PairVisitor<'de, E>
where
E: de::Error,
@@ -1832,6 +1853,7 @@ mod content {
struct ExpectedInMap(usize);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Expected for ExpectedInMap {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.0 == 1 {
@@ -1864,6 +1886,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E>
where
E: de::Error,
@@ -1892,6 +1915,7 @@ mod content {
err: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E>
where
E: de::Error,
@@ -2046,6 +2070,7 @@ mod content {
/// Used when deserializing an untagged enum because the content may need
/// to be used more than once.
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2424,8 +2449,10 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> {
fn clone(&self) -> Self {
*self
@@ -2467,6 +2494,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> Deserializer<'de> for SeqRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2489,6 +2517,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2563,6 +2592,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> Deserializer<'de> for MapRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2602,6 +2632,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> MapAccess<'de> for MapRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2656,6 +2687,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> SeqAccess<'de> for MapRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2682,6 +2714,7 @@ mod content {
struct PairRefDeserializer<'a, 'de, E>(&'a Content<'de>, &'a Content<'de>, PhantomData<E>);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> Deserializer<'de> for PairRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2737,6 +2770,7 @@ mod content {
PhantomData<E>,
);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> SeqAccess<'de> for PairRefVisitor<'a, 'de, E>
where
E: de::Error,
@@ -2776,6 +2810,7 @@ mod content {
err: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2804,6 +2839,7 @@ mod content {
err: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2890,6 +2926,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E>
where
E: de::Error,
@@ -2901,6 +2938,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2930,6 +2968,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
type Value = ();
@@ -2975,6 +3014,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> {
type Value = ();
@@ -3022,6 +3062,7 @@ pub trait IdentifierDeserializer<'de, E: Error> {
pub struct Borrowed<'de, T: 'de + ?Sized>(pub &'de T);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> IdentifierDeserializer<'de, E> for u64
where
E: Error,
@@ -3038,6 +3079,7 @@ pub struct StrDeserializer<'a, E> {
marker: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
where
E: Error,
@@ -3063,6 +3105,7 @@ pub struct BorrowedStrDeserializer<'de, E> {
marker: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E>
where
E: Error,
@@ -3083,6 +3126,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
where
E: Error,
@@ -3097,6 +3141,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, str>
where
E: Error,
@@ -3111,6 +3156,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
where
E: Error,
@@ -3122,6 +3168,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, [u8]>
where
E: Error,
@@ -3164,6 +3211,7 @@ macro_rules! forward_to_deserialize_other {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
where
E: Error,
@@ -3300,6 +3348,7 @@ struct FlatMapAccess<'a, 'de: 'a, E> {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
where
E: Error,
@@ -3344,6 +3393,7 @@ struct FlatStructAccess<'a, 'de: 'a, E> {
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
where
E: Error,
@@ -3407,6 +3457,7 @@ pub struct AdjacentlyTaggedEnumVariantVisitor<F> {
fields_enum: PhantomData<F>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, F> Visitor<'de> for AdjacentlyTaggedEnumVariantVisitor<F>
where
F: Deserialize<'de>,
@@ -3427,6 +3478,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariantSeed<F>
where
F: Deserialize<'de>,
+1 -1
View File
@@ -12,7 +12,7 @@ pub use crate::lib::option::Option::{self, None, Some};
pub use crate::lib::ptr;
pub use crate::lib::result::Result::{self, Err, Ok};
pub use serde_core::__private::string::from_utf8_lossy;
pub use crate::serde_core_private::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))]
pub use crate::lib::{ToString, Vec};
+20
View File
@@ -58,6 +58,7 @@ enum Unsupported {
Enum,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Display for Unsupported {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match *self {
@@ -89,6 +90,7 @@ where
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<S> Serializer for TaggedSerializer<S>
where
S: Serializer,
@@ -355,6 +357,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<M> ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue<M>
where
M: ser::SerializeMap,
@@ -395,6 +398,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<M> ser::SerializeStructVariant for SerializeStructVariantAsMapValue<M>
where
M: ser::SerializeMap,
@@ -462,6 +466,7 @@ mod content {
),
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Serialize for Content {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -554,6 +559,7 @@ mod content {
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> Serializer for ContentSerializer<E>
where
E: ser::Error,
@@ -765,6 +771,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeSeq for SerializeSeq<E>
where
E: ser::Error,
@@ -791,6 +798,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeTuple for SerializeTuple<E>
where
E: ser::Error,
@@ -818,6 +826,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
where
E: ser::Error,
@@ -847,6 +856,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
where
E: ser::Error,
@@ -879,6 +889,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeMap for SerializeMap<E>
where
E: ser::Error,
@@ -930,6 +941,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeStruct for SerializeStruct<E>
where
E: ser::Error,
@@ -959,6 +971,7 @@ mod content {
error: PhantomData<E>,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
where
E: ser::Error,
@@ -1003,6 +1016,7 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, M> Serializer for FlatMapSerializer<'a, M>
where
M: SerializeMap + 'a,
@@ -1184,6 +1198,7 @@ where
pub struct FlatMapSerializeMap<'a, M: 'a>(&'a mut M);
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, M> ser::SerializeMap for FlatMapSerializeMap<'a, M>
where
M: SerializeMap + 'a,
@@ -1222,6 +1237,7 @@ where
pub struct FlatMapSerializeStruct<'a, M: 'a>(&'a mut M);
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, M> ser::SerializeStruct for FlatMapSerializeStruct<'a, M>
where
M: SerializeMap + 'a,
@@ -1263,6 +1279,7 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M>
where
M: SerializeMap + 'a,
@@ -1309,6 +1326,7 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, M> ser::SerializeStructVariant for FlatMapSerializeStructVariantAsMapValue<'a, M>
where
M: SerializeMap + 'a,
@@ -1339,6 +1357,7 @@ pub struct AdjacentlyTaggedEnumVariant {
pub variant_name: &'static str,
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Serialize for AdjacentlyTaggedEnumVariant {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -1352,6 +1371,7 @@ impl Serialize for AdjacentlyTaggedEnumVariant {
// that is not recognized.
pub struct CannotSerializeVariant<T>(pub T);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<T> Display for CannotSerializeVariant<T>
where
T: Debug,
+3 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_core"
version = "1.0.223"
version = "1.0.226"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -25,6 +25,7 @@ features = ["rc", "result", "unstable"]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = [
"--generate-link-to-definition",
"--generate-macro-expansion",
"--extern-html-root-url=core=https://doc.rust-lang.org",
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
"--extern-html-root-url=std=https://doc.rust-lang.org",
@@ -36,7 +37,7 @@ rustdoc-args = [
# is compatible with exactly one serde release because the generated code
# involves nonpublic APIs which are not bound by semver.
[target.'cfg(any())'.dependencies]
serde_derive = { version = "=1.0.223", path = "../serde_derive" }
serde_derive = { version = "=1.0.226", path = "../serde_derive" }
### FEATURES #################################################################
+15
View File
@@ -1,13 +1,28 @@
use std::env;
use std::fs;
use std::path::PathBuf;
use std::process::Command;
use std::str;
const PRIVATE: &str = "\
#[doc(hidden)]
pub mod __private$$ {
#[doc(hidden)]
pub use crate::private::*;
}
";
// The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let patch_version = env::var("CARGO_PKG_VERSION_PATCH").unwrap();
let module = PRIVATE.replace("$$", &patch_version);
fs::write(out_dir.join("private.rs"), module).unwrap();
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
+13 -4
View File
@@ -35,7 +35,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde_core/1.0.223")]
#![doc(html_root_url = "https://docs.rs/serde_core/1.0.226")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
@@ -252,9 +252,18 @@ pub use crate::ser::{Serialize, Serializer};
// Used by generated code. Not public API.
#[doc(hidden)]
#[path = "private/mod.rs"]
pub mod __private;
use self::__private as private;
mod private;
// Used by declarative macro generated code. Not public API.
#[doc(hidden)]
pub mod __private {
#[doc(hidden)]
pub use crate::private::doc;
#[doc(hidden)]
pub use core::result::Result;
}
include!(concat!(env!("OUT_DIR"), "/private.rs"));
#[cfg(all(not(feature = "std"), no_core_error))]
mod std_error;
+3
View File
@@ -8,6 +8,7 @@ use crate::ser;
#[derive(Debug)]
pub struct Error;
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl ser::Error for Error {
fn custom<T>(_: T) -> Self
where
@@ -18,12 +19,14 @@ impl ser::Error for Error {
}
#[cfg(feature = "std")]
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl error::Error for Error {
fn description(&self) -> &str {
unimplemented!()
}
}
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl Display for Error {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
+1
View File
@@ -5,6 +5,7 @@ use crate::de::{Deserialize, DeserializeSeed, Deserializer};
/// Wraps a mutable reference and calls deserialize_in_place on it.
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
#[cfg_attr(not(no_diagnostic_namespace), diagnostic::do_not_recommend)]
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
where
T: Deserialize<'de>,
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.223"
version = "1.0.226"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -34,6 +34,7 @@ serde = { version = "1", path = "../serde" }
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = [
"--generate-link-to-definition",
"--generate-macro-expansion",
"--extern-html-root-url=core=https://doc.rust-lang.org",
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
"--extern-html-root-url=std=https://doc.rust-lang.org",
+298 -285
View File
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
use proc_macro2::TokenStream;
use quote::quote;
pub fn allow_deprecated(input: &syn::DeriveInput) -> Option<TokenStream> {
if should_allow_deprecated(input) {
Some(quote! { #[allow(deprecated)] })
} else {
None
}
}
/// Determine if an `#[allow(deprecated)]` should be added to the derived impl.
///
/// This should happen if the derive input or an enum variant it contains has
/// one of:
/// - `#[deprecated]`
/// - `#[allow(deprecated)]`
fn should_allow_deprecated(input: &syn::DeriveInput) -> bool {
if contains_deprecated(&input.attrs) {
return true;
}
if let syn::Data::Enum(data_enum) = &input.data {
for variant in &data_enum.variants {
if contains_deprecated(&variant.attrs) {
return true;
}
}
}
false
}
/// Check whether the given attributes contains one of:
/// - `#[deprecated]`
/// - `#[allow(deprecated)]`
fn contains_deprecated(attrs: &[syn::Attribute]) -> bool {
for attr in attrs {
if attr.path().is_ident("deprecated") {
return true;
}
if let syn::Meta::List(meta_list) = &attr.meta {
if meta_list.path.is_ident("allow") {
let mut allow_deprecated = false;
let _ = meta_list.parse_nested_meta(|meta| {
if meta.path.is_ident("deprecated") {
allow_deprecated = true;
}
Ok(())
});
if allow_deprecated {
return true;
}
}
}
}
false
}
+21 -8
View File
@@ -1,6 +1,7 @@
//! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
use crate::internals::{attr, check, Ctxt, Derive};
use proc_macro2::Ident;
use syn::punctuated::Punctuated;
use syn::Token;
@@ -62,13 +63,17 @@ impl<'a> Container<'a> {
cx: &Ctxt,
item: &'a syn::DeriveInput,
derive: Derive,
private: &Ident,
) -> Option<Container<'a>> {
let attrs = attr::Container::from_ast(cx, item);
let mut data = match &item.data {
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
syn::Data::Enum(data) => {
Data::Enum(enum_from_ast(cx, &data.variants, attrs.default(), private))
}
syn::Data::Struct(data) => {
let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
let (style, fields) =
struct_from_ast(cx, &data.fields, None, attrs.default(), private);
Data::Struct(style, fields)
}
syn::Data::Union(_) => {
@@ -129,13 +134,19 @@ fn enum_from_ast<'a>(
cx: &Ctxt,
variants: &'a Punctuated<syn::Variant, Token![,]>,
container_default: &attr::Default,
private: &Ident,
) -> Vec<Variant<'a>> {
let variants: Vec<Variant> = variants
.iter()
.map(|variant| {
let attrs = attr::Variant::from_ast(cx, variant);
let (style, fields) =
struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
let (style, fields) = struct_from_ast(
cx,
&variant.fields,
Some(&attrs),
container_default,
private,
);
Variant {
ident: variant.ident.clone(),
attrs,
@@ -165,19 +176,20 @@ fn struct_from_ast<'a>(
fields: &'a syn::Fields,
attrs: Option<&attr::Variant>,
container_default: &attr::Default,
private: &Ident,
) -> (Style, Vec<Field<'a>>) {
match fields {
syn::Fields::Named(fields) => (
Style::Struct,
fields_from_ast(cx, &fields.named, attrs, container_default),
fields_from_ast(cx, &fields.named, attrs, container_default, private),
),
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => (
Style::Newtype,
fields_from_ast(cx, &fields.unnamed, attrs, container_default),
fields_from_ast(cx, &fields.unnamed, attrs, container_default, private),
),
syn::Fields::Unnamed(fields) => (
Style::Tuple,
fields_from_ast(cx, &fields.unnamed, attrs, container_default),
fields_from_ast(cx, &fields.unnamed, attrs, container_default, private),
),
syn::Fields::Unit => (Style::Unit, Vec::new()),
}
@@ -188,6 +200,7 @@ fn fields_from_ast<'a>(
fields: &'a Punctuated<syn::Field, Token![,]>,
attrs: Option<&attr::Variant>,
container_default: &attr::Default,
private: &Ident,
) -> Vec<Field<'a>> {
fields
.iter()
@@ -197,7 +210,7 @@ fn fields_from_ast<'a>(
Some(ident) => syn::Member::Named(ident.clone()),
None => syn::Member::Unnamed(i.into()),
},
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default, private),
ty: &field.ty,
original: field,
})
+4 -9
View File
@@ -3,14 +3,13 @@ use crate::internals::symbol::*;
use crate::internals::{ungroup, Ctxt};
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
use quote::ToTokens;
use std::borrow::Cow;
use std::collections::BTreeSet;
use std::iter::FromIterator;
use syn::meta::ParseNestedMeta;
use syn::parse::ParseStream;
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{parse_quote, token, Ident, Lifetime, Token};
use syn::{token, Ident, Lifetime, Token};
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
@@ -609,11 +608,6 @@ impl Container {
self.serde_path.as_ref()
}
pub fn serde_path(&self) -> Cow<syn::Path> {
self.custom_serde_path()
.map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
}
/// Error message generated when type can't be deserialized.
/// If `None`, default message will be used
pub fn expecting(&self) -> Option<&str> {
@@ -1024,6 +1018,7 @@ impl Field {
field: &syn::Field,
attrs: Option<&Variant>,
container_default: &Default,
private: &Ident,
) -> Self {
let mut ser_name = Attr::none(cx, RENAME);
let mut de_name = Attr::none(cx, RENAME);
@@ -1217,7 +1212,7 @@ impl Field {
};
let span = Span::call_site();
path.segments.push(Ident::new("_serde", span).into());
path.segments.push(Ident::new("__private", span).into());
path.segments.push(private.clone().into());
path.segments.push(Ident::new("de", span).into());
path.segments
.push(Ident::new("borrow_cow_str", span).into());
@@ -1234,7 +1229,7 @@ impl Field {
};
let span = Span::call_site();
path.segments.push(Ident::new("_serde", span).into());
path.segments.push(Ident::new("__private", span).into());
path.segments.push(private.clone().into());
path.segments.push(Ident::new("de", span).into());
path.segments
.push(Ident::new("borrow_cow_bytes", span).into());
+22 -1
View File
@@ -13,7 +13,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.223")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.226")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints
#![allow(
@@ -75,6 +75,8 @@ extern crate proc_macro;
mod internals;
use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::{ToTokens, TokenStreamExt as _};
use syn::parse_macro_input;
use syn::DeriveInput;
@@ -84,11 +86,30 @@ mod bound;
mod fragment;
mod de;
mod deprecated;
mod dummy;
mod pretend;
mod ser;
mod this;
#[allow(non_camel_case_types)]
struct private;
impl private {
fn ident(&self) -> Ident {
Ident::new(
concat!("__private", env!("CARGO_PKG_VERSION_PATCH")),
Span::call_site(),
)
}
}
impl ToTokens for private {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
tokens.append(self.ident());
}
}
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
+12 -9
View File
@@ -1,4 +1,5 @@
use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::private;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
@@ -83,8 +84,8 @@ fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
match _serde::#private::None::<&#type_ident #ty_generics> {
_serde::#private::Some(#type_ident { #(#members: #placeholders),* }) => {}
_ => {}
}
}
@@ -96,11 +97,12 @@ fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> Toke
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
let private2 = private;
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
match _serde::#private::None::<&#type_ident #ty_generics> {
_serde::#private::Some(__v @ #type_ident { #(#members: _),* }) => {
#(
let _ = _serde::__private::ptr::addr_of!(__v.#members);
let _ = _serde::#private2::ptr::addr_of!(__v.#members);
)*
}
_ => {}
@@ -125,10 +127,11 @@ fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStre
})
.collect::<Vec<_>>();
let private2 = private;
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
match _serde::#private::None::<&#type_ident #ty_generics> {
#(
_serde::__private::Some(#patterns) => {}
_serde::#private2::Some(#patterns) => {}
)*
_ => {}
}
@@ -172,8 +175,8 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
};
quote! {
match _serde::__private::None {
_serde::__private::Some((#(#placeholders,)*)) => {
match _serde::#private::None {
_serde::#private::Some((#(#placeholders,)*)) => {
let _ = #type_ident::#variant_ident #turbofish #pat;
}
_ => {}
+33 -30
View File
@@ -1,8 +1,9 @@
use crate::deprecated::allow_deprecated;
use crate::fragment::{Fragment, Match, Stmts};
use crate::internals::ast::{Container, Data, Field, Style, Variant};
use crate::internals::name::Name;
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
use crate::{bound, dummy, pretend, this};
use crate::{bound, dummy, pretend, private, this};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned};
use syn::spanned::Spanned;
@@ -12,7 +13,7 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
replace_receiver(input);
let ctxt = Ctxt::new();
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize, &private.ident()) {
Some(cont) => cont,
None => return Err(ctxt.check().unwrap_err()),
};
@@ -23,17 +24,18 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let body = Stmts(serialize_body(&cont, &params));
let serde = cont.attrs.serde_path();
let allow_deprecated = allow_deprecated(input);
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let used = pretend::pretend_used(&cont, params.is_packed);
quote! {
#[automatically_derived]
#allow_deprecated
impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where
__S: #serde::Serializer,
__S: _serde::Serializer,
{
#used
#body
@@ -43,10 +45,11 @@ pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<Toke
} else {
quote! {
#[automatically_derived]
impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
#allow_deprecated
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where
__S: #serde::Serializer,
__S: _serde::Serializer,
{
#body
}
@@ -212,7 +215,7 @@ fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
let self_var = &params.self_var;
quote_block! {
_serde::Serialize::serialize(
&_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)),
&_serde::#private::Into::<#type_into>::into(_serde::#private::Clone::clone(#self_var)),
__serializer)
}
}
@@ -382,7 +385,7 @@ fn serialize_struct_as_map(
let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::__private::None)?;
let #let_mut __serde_state = _serde::Serializer::serialize_map(__serializer, _serde::#private::None)?;
#tag_field
#(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state)
@@ -404,7 +407,7 @@ fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Cont
if cattrs.remote().is_some() && cattrs.non_exhaustive() {
arms.push(quote! {
ref unrecognized => _serde::__private::Err(_serde::ser::Error::custom(_serde::__private::ser::CannotSerializeVariant(unrecognized))),
ref unrecognized => _serde::#private::Err(_serde::ser::Error::custom(_serde::#private::ser::CannotSerializeVariant(unrecognized))),
});
}
@@ -431,7 +434,7 @@ fn serialize_variant(
variant_ident
);
let skipped_err = quote! {
_serde::__private::Err(_serde::ser::Error::custom(#skipped_msg))
_serde::#private::Err(_serde::ser::Error::custom(#skipped_msg))
};
let fields_pat = match variant.style {
Style::Unit => quote!(),
@@ -585,7 +588,7 @@ fn serialize_internally_tagged_variant(
if let Some(path) = variant.attrs.serialize_with() {
let ser = wrap_serialize_variant_with(params, path, variant);
return quote_expr! {
_serde::__private::ser::serialize_tagged_newtype(
_serde::#private::ser::serialize_tagged_newtype(
__serializer,
#enum_ident_str,
#variant_ident_str,
@@ -614,7 +617,7 @@ fn serialize_internally_tagged_variant(
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype);
let func = quote_spanned!(span=> _serde::#private::ser::serialize_tagged_newtype);
quote_expr! {
#func(
__serializer,
@@ -648,7 +651,7 @@ fn serialize_adjacently_tagged_variant(
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
let serialize_variant = quote! {
&_serde::__private::ser::AdjacentlyTaggedEnumVariant {
&_serde::#private::ser::AdjacentlyTaggedEnumVariant {
enum_name: #type_name,
variant_index: #variant_index,
variant_name: #variant_name,
@@ -731,12 +734,12 @@ fn serialize_adjacently_tagged_variant(
#[doc(hidden)]
struct __AdjacentlyTagged #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData<#this_type #ty_generics>,
}
#[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
@@ -754,7 +757,7 @@ fn serialize_adjacently_tagged_variant(
_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, &__AdjacentlyTagged {
data: (#(#fields_ident,)*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
})?;
_serde::ser::SerializeStruct::end(__struct)
}
@@ -996,19 +999,19 @@ fn serialize_struct_variant_with_flatten(
#[doc(hidden)]
struct __EnumFlatten #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData<#this_type #ty_generics>,
}
#[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
fn serialize<__S>(&self, __serializer: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
let (#(#members,)*) = self.data;
let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer,
_serde::__private::None)?;
_serde::#private::None)?;
#(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state)
}
@@ -1021,7 +1024,7 @@ fn serialize_struct_variant_with_flatten(
#variant_name,
&__EnumFlatten {
data: (#(#members,)*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
})
}
}
@@ -1029,7 +1032,7 @@ fn serialize_struct_variant_with_flatten(
quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer,
_serde::__private::None)?;
_serde::#private::None)?;
_serde::ser::SerializeMap::serialize_entry(
&mut __serde_state,
#tag,
@@ -1043,7 +1046,7 @@ fn serialize_struct_variant_with_flatten(
quote_block! {
let #let_mut __serde_state = _serde::Serializer::serialize_map(
__serializer,
_serde::__private::None)?;
_serde::#private::None)?;
#(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state)
}
@@ -1132,7 +1135,7 @@ fn serialize_struct_visitor(
let ser = if field.attrs.flatten() {
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote! {
#func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state))?;
#func(&#field_expr, _serde::#private::ser::FlatMapSerializer(&mut __serde_state))?;
}
} else {
let func = struct_trait.serialize_field(span);
@@ -1239,12 +1242,12 @@ fn wrap_serialize_with(
#[doc(hidden)]
struct __SerializeWith #wrapper_impl_generics #where_clause {
values: (#(&'__a #field_tys, )*),
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData<#this_type #ty_generics>,
}
#[automatically_derived]
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::#private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
@@ -1254,7 +1257,7 @@ fn wrap_serialize_with(
__SerializeWith {
values: (#(#field_exprs, )*),
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
phantom: _serde::#private::PhantomData::<#this_type #ty_generics>,
}
})
}
@@ -1290,11 +1293,11 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStrea
quote!(&#self_var.#member)
};
let ty = field.ty;
quote!(_serde::__private::ser::constrain::<#ty>(#inner))
quote!(_serde::#private::ser::constrain::<#ty>(#inner))
}
(true, Some(getter)) => {
let ty = field.ty;
quote!(_serde::__private::ser::constrain::<#ty>(&#getter(#self_var)))
quote!(_serde::#private::ser::constrain::<#ty>(&#getter(#self_var)))
}
(false, Some(_)) => {
unreachable!("getter is only allowed for remote impls");
+1
View File
@@ -24,6 +24,7 @@ syn = { workspace = true, features = ["clone-impls", "derive", "parsing", "print
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = [
"--generate-link-to-definition",
"--generate-macro-expansion",
"--extern-html-root-url=core=https://doc.rust-lang.org",
"--extern-html-root-url=alloc=https://doc.rust-lang.org",
"--extern-html-root-url=std=https://doc.rust-lang.org",
+620 -56
View File
@@ -2697,23 +2697,42 @@ mod flatten {
#[test]
fn newtype() {
let value = Flatten {
data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])),
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
};
assert_tokens(
&Flatten {
data: Enum::Newtype(HashMap::from_iter([("key".into(), "value".into())])),
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
},
&value,
&[
Token::Map { len: None },
// data
Token::Str("Newtype"), // variant
Token::Map { len: Some(1) },
Token::Str("key"),
Token::Str("value"),
Token::MapEnd,
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
// data
Token::Str("Newtype"), // variant
Token::Map { len: Some(1) },
Token::Str("key"),
Token::Str("value"),
Token::MapEnd,
Token::MapEnd,
],
);
}
// Reaches crate::private::de::content::VariantDeserializer::tuple_variant
@@ -2721,23 +2740,42 @@ mod flatten {
// via FlatMapDeserializer::deserialize_enum
#[test]
fn tuple() {
let value = Flatten {
data: Enum::Tuple(0, 42),
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
};
assert_tokens(
&Flatten {
data: Enum::Tuple(0, 42),
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
},
&value,
&[
Token::Map { len: None },
// data
Token::Str("Tuple"), // variant
Token::Seq { len: Some(2) },
Token::U32(0),
Token::U32(42),
Token::SeqEnd,
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
// data
Token::Str("Tuple"), // variant
Token::Seq { len: Some(2) },
Token::U32(0),
Token::U32(42),
Token::SeqEnd,
Token::MapEnd,
],
);
}
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
@@ -2745,26 +2783,45 @@ mod flatten {
// via FlatMapDeserializer::deserialize_enum
#[test]
fn struct_from_seq() {
assert_de_tokens(
&Flatten {
data: Enum::Struct {
index: 0,
value: 42,
},
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
let value = Flatten {
data: Enum::Struct {
index: 0,
value: 42,
},
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
};
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// data
Token::Str("Struct"), // variant
Token::Seq { len: Some(2) },
Token::U32(0), // index
Token::U32(42), // value
Token::SeqEnd,
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
// data
Token::Str("Struct"), // variant
Token::Seq { len: Some(2) },
Token::U32(0), // index
Token::U32(42), // value
Token::SeqEnd,
Token::MapEnd,
],
);
}
// Reaches crate::private::de::content::VariantDeserializer::struct_variant
@@ -2772,16 +2829,18 @@ mod flatten {
// via FlatMapDeserializer::deserialize_enum
#[test]
fn struct_from_map() {
assert_tokens(
&Flatten {
data: Enum::Struct {
index: 0,
value: 42,
},
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
let value = Flatten {
data: Enum::Struct {
index: 0,
value: 42,
},
extra: HashMap::from_iter([("extra_key".into(), "extra value".into())]),
};
assert_tokens(
&value,
&[
Token::Map { len: None },
// data
Token::Str("Struct"), // variant
Token::Struct {
len: 2,
@@ -2792,11 +2851,33 @@ mod flatten {
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// extra
Token::Str("extra_key"),
Token::Str("extra value"),
// data
Token::Str("Struct"), // variant
Token::Struct {
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
Token::MapEnd,
],
);
}
}
@@ -2817,6 +2898,7 @@ mod flatten {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "tag", content = "content")]
enum Enum {
Unit,
Newtype(NewtypeVariant),
Struct { index: u32, value: u32 },
}
@@ -2827,24 +2909,357 @@ mod flatten {
}
#[test]
fn struct_() {
fn unit() {
let value = Flatten {
outer: 42,
data: NewtypeWrapper(Enum::Unit),
};
// Field order: outer, [tag]
assert_tokens(
&Flatten {
outer: 42,
data: NewtypeWrapper(Enum::Struct {
index: 0,
value: 42,
}),
},
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// content missing
Token::MapEnd,
],
);
// Field order: [tag], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// content missing
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: outer, [tag, content]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// content
Token::Str("content"),
Token::Unit,
Token::MapEnd,
],
);
// Field order: outer, [content, tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Unit,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
Token::MapEnd,
],
);
// Field order: [tag, content], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// content
Token::Str("content"),
Token::Unit,
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [content, tag], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Unit,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [tag], outer, [content]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Unit,
Token::MapEnd,
],
);
// Field order: [content], outer, [tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Unit,
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Unit",
},
Token::MapEnd,
],
);
}
#[test]
fn newtype() {
let value = Flatten {
outer: 42,
data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })),
};
// Field order: outer, [tag, content]
assert_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
Token::MapEnd,
],
);
// Field order: outer, [content, tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
Token::MapEnd,
],
);
// Field order: [tag, content], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [content, tag], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [tag], outer, [content]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
Token::MapEnd,
],
);
// Field order: [content], outer, [tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
Token::MapEnd,
],
);
}
#[test]
fn struct_() {
let value = Flatten {
outer: 42,
data: NewtypeWrapper(Enum::Struct {
index: 0,
value: 42,
}),
};
// Field order: outer, [tag, content]
assert_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
// content
Token::Str("content"),
Token::Struct {
len: 2,
@@ -2858,32 +3273,143 @@ mod flatten {
Token::MapEnd,
],
);
}
#[test]
fn newtype() {
assert_tokens(
&Flatten {
outer: 42,
data: NewtypeWrapper(Enum::Newtype(NewtypeVariant { value: 23 })),
},
// Field order: outer, [content, tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Struct {
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Newtype",
variant: "Struct",
},
Token::MapEnd,
],
);
// Field order: [tag, content], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
// content
Token::Str("content"),
Token::Struct {
len: 1,
name: "NewtypeVariant",
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(23),
Token::U32(42),
Token::StructEnd,
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [content, tag], outer
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Struct {
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
// outer
Token::Str("outer"),
Token::U32(42),
Token::MapEnd,
],
);
// Field order: [tag], outer, [content]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
// outer
Token::Str("outer"),
Token::U32(42),
// content
Token::Str("content"),
Token::Struct {
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
Token::MapEnd,
],
);
// Field order: [content], outer, [tag]
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// content
Token::Str("content"),
Token::Struct {
len: 2,
name: "Struct",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
Token::U32(42),
Token::StructEnd,
// outer
Token::Str("outer"),
Token::U32(42),
// tag
Token::Str("tag"),
Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
Token::MapEnd,
],
);
@@ -2917,17 +3443,20 @@ mod flatten {
D { d: i32 },
}
let value = Flatten {
x: X::B { b: 1 },
y: Y::D { d: 2 },
};
assert_tokens(
&Flatten {
x: X::B { b: 1 },
y: Y::D { d: 2 },
},
&value,
&[
Token::Map { len: None },
// x
Token::Str("typeX"),
Token::Str("B"),
Token::Str("b"),
Token::I32(1),
// y
Token::Str("typeY"),
Token::Str("D"),
Token::Str("d"),
@@ -2935,11 +3464,28 @@ mod flatten {
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// y
Token::Str("typeY"),
Token::Str("D"),
Token::Str("d"),
Token::I32(2),
// x
Token::Str("typeX"),
Token::Str("B"),
Token::Str("b"),
Token::I32(1),
Token::MapEnd,
],
);
}
#[test]
fn unit_enum_with_unknown_fields() {
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Flatten {
#[serde(flatten)]
x: X,
@@ -2947,31 +3493,49 @@ mod flatten {
y: Y,
}
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "typeX")]
enum X {
A,
}
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "typeY")]
enum Y {
B { c: u32 },
}
assert_de_tokens(
&Flatten {
x: X::A,
y: Y::B { c: 0 },
},
let value = Flatten {
x: X::A,
y: Y::B { c: 0 },
};
assert_tokens(
&value,
&[
Token::Map { len: None },
// x
Token::Str("typeX"),
Token::Str("A"),
// y
Token::Str("typeY"),
Token::Str("B"),
Token::Str("c"),
Token::I32(0),
Token::U32(0),
Token::MapEnd,
],
);
assert_de_tokens(
&value,
&[
Token::Map { len: None },
// y
Token::Str("typeY"),
Token::Str("B"),
Token::Str("c"),
Token::U32(0),
// x
Token::Str("typeX"),
Token::Str("A"),
Token::MapEnd,
],
);
+30
View File
@@ -0,0 +1,30 @@
#![deny(deprecated)]
#![allow(dead_code)]
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[deprecated]
enum DeprecatedEnum {
A,
B,
}
#[derive(Serialize, Deserialize)]
#[deprecated]
struct DeprecatedStruct {
a: bool,
}
#[derive(Serialize, Deserialize)]
enum DeprecatedVariant {
A,
#[deprecated]
B,
}
#[derive(Serialize, Deserialize)]
struct DeprecatedField {
#[deprecated]
a: bool,
}
@@ -0,0 +1,20 @@
#![deny(deprecated)]
use serde::Deserializer;
use serde_derive::Deserialize;
#[derive(Deserialize)]
pub struct Struct {
#[serde(deserialize_with = "deprecated_with")]
pub field: i32,
}
#[deprecated]
fn deprecated_with<'de, D>(_deserializer: D) -> Result<i32, D::Error>
where
D: Deserializer<'de>,
{
unimplemented!()
}
fn main() {}
@@ -0,0 +1,11 @@
error: use of deprecated function `deprecated_with`
--> tests/ui/deprecated/deprecated_de_with.rs:8:32
|
8 | #[serde(deserialize_with = "deprecated_with")]
| ^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui/deprecated/deprecated_de_with.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^
@@ -0,0 +1,20 @@
#![deny(deprecated)]
use serde::Serializer;
use serde_derive::Serialize;
#[derive(Serialize)]
pub struct Struct {
#[serde(serialize_with = "deprecated_with")]
pub field: i32,
}
#[deprecated]
fn deprecated_with<S>(_field: &i32, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
unimplemented!()
}
fn main() {}
@@ -0,0 +1,11 @@
error: use of deprecated function `deprecated_with`
--> tests/ui/deprecated/deprecated_ser_with.rs:8:30
|
8 | #[serde(serialize_with = "deprecated_with")]
| ^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/ui/deprecated/deprecated_ser_with.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^
+4 -16
View File
@@ -6,10 +6,7 @@ error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
15 | struct W(#[serde(with = "w")] u8, u8);
| --- required by a bound introduced by this call
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
= help: the trait `Serializer` is implemented for `&mut Formatter<'a>`
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
@@ -36,10 +33,7 @@ error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
15 | struct W(#[serde(with = "w")] u8, u8);
| ^^^ the trait `Serializer` is not implemented for `&u8`
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
= help: the trait `Serializer` is implemented for `&mut Formatter<'a>`
error[E0308]: `?` operator has incompatible types
--> tests/ui/with/incorrect_type.rs:15:25
@@ -57,10 +51,7 @@ error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| -------------- required by a bound introduced by this call
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
= help: the trait `Serializer` is implemented for `&mut Formatter<'a>`
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
@@ -87,10 +78,7 @@ error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| ^^^^^^^^^^^^^^ the trait `Serializer` is not implemented for `&u8`
|
= help: the following other types implement trait `Serializer`:
&mut Formatter<'a>
FlatMapSerializer<'a, M>
_::_serde::__private::ser::content::ContentSerializer<E>
= help: the trait `Serializer` is implemented for `&mut Formatter<'a>`
error[E0308]: `?` operator has incompatible types
--> tests/ui/with/incorrect_type.rs:21:37