Compare commits

...

72 Commits

Author SHA1 Message Date
David Tolnay ff3aee490a Release 1.0.221 2025-09-13 17:25:20 -07:00
David Tolnay 10bcfc0047 Merge pull request #2975 from dtolnay/integer128
Deprecate serde_if_integer128 macro
2025-09-13 17:25:14 -07:00
David Tolnay 2f03899197 Deprecate serde_if_integer128 macro 2025-09-13 17:19:10 -07:00
David Tolnay 3bea3b6989 Move serde_if_integer128 macro to serde 2025-09-13 17:12:58 -07:00
David Tolnay 85bf29c446 Merge pull request #2973 from dtolnay/timings
Illustrate build timings in serde_core readme
2025-09-13 17:12:51 -07:00
David Tolnay 900c922f41 Illustrate build timings in serde_core readme 2025-09-13 17:09:47 -07:00
David Tolnay 9cf3f2ed7d Merge pull request #2974 from dtolnay/patchserdecore
Patch serde_core at workspace level
2025-09-13 17:04:36 -07:00
David Tolnay 1ffbeb9516 Patch serde_core at workspace level 2025-09-13 16:59:44 -07:00
David Tolnay 1051c5e6b7 Enforce trybuild >= 1.0.108
Older versions produce slightly differently normalized output
when run against 1.90.0+ Rust compiler.
2025-09-13 14:49:14 -07:00
David Tolnay be255d62c8 Release 1.0.220 2025-09-13 14:45:43 -07:00
David Tolnay 263a1dbdd7 Link to serde.rs without trailing slash 2025-09-13 14:40:22 -07:00
David Tolnay 23dea60e1a Merge pull request #2971 from dtolnay/serdecoreci
Add CI coverage of serde_core
2025-09-13 14:40:13 -07:00
David Tolnay 690785f129 Add CI coverage of serde_core 2025-09-13 14:36:11 -07:00
David Tolnay 69aa109fd3 Merge pull request #2970 from dtolnay/coredoctest
Fix serde_core doc tests
2025-09-13 14:36:00 -07:00
David Tolnay 6bea2e04e4 Move doc helper macros to serde_core 2025-09-13 14:32:21 -07:00
David Tolnay a1a82c3c55 Replace serde_core::* glob export 2025-09-13 14:32:21 -07:00
David Tolnay 7987ad700e Fix serde_core doc tests 2025-09-13 14:32:21 -07:00
David Tolnay 0990d97a77 Merge pull request #2969 from dtolnay/coreprivate
Reduce visibility of serde_core implementation details
2025-09-13 14:32:12 -07:00
David Tolnay a9150aad74 Make serde_core::Result private 2025-09-13 14:29:23 -07:00
David Tolnay 5ac3d84d99 Make InPlaceSeed private 2025-09-13 14:29:23 -07:00
David Tolnay f916ec6baa Make size_hint private 2025-09-13 14:29:22 -07:00
David Tolnay 7f831225a9 Make from_utf8_lossy private 2025-09-13 14:29:01 -07:00
David Tolnay a16893429b Make module for Content-related private code 2025-09-13 14:26:58 -07:00
David Tolnay 260511d149 Merge pull request #2968 from dtolnay/deserializecontent
Restore `__deserialize_content` optimization
2025-09-13 14:26:50 -07:00
David Tolnay 7659fb686d Inline SeqDeserializer and MapDeserializer for Content
Greatly shrinks symbol sizes: keep all those generic type parameters
(and even closures) out of symbol names. A good change even independent
of serde_core.
2025-09-13 14:22:33 -07:00
David Tolnay f669f16127 Restore __deserialize_content optimization 2025-09-13 14:22:33 -07:00
David Tolnay 93f43cedaa Merge pull request #2967 from dtolnay/tricfg
Specify the cfg in which `tri!` is used
2025-09-13 14:22:25 -07:00
David Tolnay b6c7ce8ec3 Specify the cfg in which 'tri!' is used 2025-09-13 14:19:07 -07:00
David Tolnay 35c963101b Merge pull request #2966 from dtolnay/noserdecore
Enforce derive cannot be used against serde_core
2025-09-13 14:19:01 -07:00
David Tolnay 8909fc0c60 Enforce derive cannot be used against serde_core
Even for a simple data structure that would ordinarily expand to an impl
that only refers to the public Serde traits without serde::__private, we
still disallow a (renamed) serde_core dependency. This leaves the
liberty to new usage of private helpers in such impls over time. For
example, similar to the optimization of the standard library's
derive(Debug) that introduced debug_struct_field1_finish to improve
compile time of derived impls.
2025-09-13 14:15:44 -07:00
David Tolnay 3c747e4585 Relocate serde_derive version constraint from serde to serde_core
This disallows using an old version of serde_derive against a new
version of serde_core (with a rename to serde in Cargo.toml).
2025-09-13 14:15:44 -07:00
David Tolnay 1b89ff50a9 Merge pull request #2965 from dtolnay/enableresult
Forcibly enable serde_core/result when using serde
2025-09-13 14:15:38 -07:00
David Tolnay c069b5c640 Forcibly enable serde_core/result when using serde
Making Result impls get disabled when using `serde = { version = "1",
default-features = false }` would have been a breaking change.
2025-09-13 14:11:44 -07:00
David Tolnay 79f3484ab8 Merge pull request #2964 from dtolnay/serdecoredoc
Update documentation of serde_core
2025-09-13 14:11:33 -07:00
David Tolnay ac8b7ea052 Update serde_core package.description in Cargo.toml 2025-09-13 14:07:54 -07:00
David Tolnay c1b2f43917 Tweak explanation of "result" feature 2025-09-13 14:07:54 -07:00
David Tolnay 51f8b0c52d Rewrite serde_core readme 2025-09-13 14:07:53 -07:00
David Tolnay 6c4cae6b09 Point API documentation to docs.rs/serde 2025-09-13 14:07:53 -07:00
David Tolnay 4da055a286 Fix broken link in serde_core crates.io readme 2025-09-13 14:07:53 -07:00
David Tolnay 66c5d2b153 Merge pull request #2963 from dtolnay/diagnosticpath
Override diagnostic::on_unimplemented message for all serde_core traits
2025-09-13 14:07:43 -07:00
David Tolnay 4bddf1b953 Override diagnostic::on_unimplemented message of all serde_core traits
This prevents diagnostics being rendered like `serde_core::ser::Serialize`
and `serde_core::de::Deserialize` in projects that have no direct
dependency on serde_core.

The attributes make error messages arguably sometimes worse than
pre-serde_core by always rendering `serde::Serialize` and never
`Serialize` when `use serde::Serialize` is in scope, which rustc's
default message construction knows to recognize. But this is probably
negligible.

I explored the alternative of setting `[lib] name = "serde"` in
serde_core/Cargo.toml which also prevents `serde_core::ser::Serialize`
in messages, but has the unwanted effect of also inserting the following
noise into every such error:

    note: there are multiple different versions of crate `serde` in the dependency graph
        --> $WORKSPACE/serde_core/src/ser/mod.rs:225:1
         |
     225 | pub trait Serialize {
         | ^^^^^^^^^^^^^^^^^^^ this is the required trait
         |
        ::: src/main.rs:1:1
         |
       1 | struct MyStruct;
         | --------------- this type doesn't implement the required trait
    ...
       4 |     let _ = serde_json::to_string(&MyStruct);
         |             ----------
         |             |
         |             one version of crate `serde` used here, as a dependency of crate `serde`
         |             one version of crate `serde` used here, as a dependency of crate `serde_json`
         |
        ::: $WORKSPACE/serde/src/private/de.rs:2347:1
         |
    2347 | pub trait IdentifierDeserializer<'de, E: Error> {
         | ----------------------------------------------- this is the found trait
         = help: you can use `cargo tree` to explore your dependency tree

The "this is the found trait" pointing to `IdentifierDeserializer` seems
like a compiler bug...
2025-09-13 13:59:52 -07:00
David Tolnay 908f32175a Add ui test of unimplemented trait required by dependency 2025-09-13 13:59:52 -07:00
David Tolnay 3e1cf11060 Organize on_unimplemented ui test into directory 2025-09-13 13:59:52 -07:00
David Tolnay 723fcacad7 Merge pull request #2608 from osiewicz/extract_serde_core
feat: Extract serde_core out of serde crate
2025-09-13 13:59:17 -07:00
David Tolnay 94acfe19e6 Format with rustfmt 1.8.0-nightly 2025-09-13 10:16:16 -07:00
Oli Scherer b4677fde9d Bump outdated test dependency 2025-08-26 08:02:38 +00:00
Oli Scherer c85e4240be Allow more dead code 2025-08-26 07:19:59 +00:00
Oli Scherer 363deb84cc Work around dead code warnings 2025-08-26 07:10:49 +00:00
Piotr Osiewicz f9baf39dc3 review: Update crates-io.md 2025-06-06 12:15:59 +02:00
Piotr Osiewicz 3deb08946e review: Gate Result impls behind a feature gate 2025-06-06 11:57:32 +02:00
Piotr Osiewicz 43f5eb5c69 review: Bring back old doc comment for serde_core 2025-06-06 11:57:32 +02:00
Piotr Osiewicz 5fcfbed3ea review: Update license symlinks 2025-06-06 11:57:32 +02:00
Piotr Osiewicz f3869307cc feat: extract serde_core out of serde 2025-06-06 11:57:32 +02:00
Oli Scherer babafa54d2 Merge pull request #2939 from Mingun/remove-actually-private
Remove `actually_private::T`
2025-06-06 06:39:39 +00:00
Mingun ad6c548573 Use associated type in signature to not repeat concrete type 2025-06-06 10:39:51 +05:00
Mingun 80b2f5f9e1 Remove actually_private::T
It just makes life harder in some cases without any benefits
2025-06-06 10:39:51 +05:00
David Tolnay 2130ba5788 Ignore mismatched_lifetime_syntaxes lint
warning: lifetime flowing from input to output with different syntax can be confusing
       --> serde/src/private/de.rs:266:23
        |
    266 |         fn unexpected(&self) -> Unexpected {
        |                       ^^^^^     ---------- the lifetime gets resolved as `'_`
        |                       |
        |                       this lifetime flows to the output
        |
        = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
    help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
        |
    266 |         fn unexpected(&self) -> Unexpected<'_> {
        |                                           ++++

    warning: lifetime flowing from input to output with different syntax can be confusing
      --> serde/src/private/mod.rs:27:35
       |
    27 |     pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
       |                                   ^^^^^     -------- the lifetime gets resolved as `'_`
       |                                   |
       |                                   this lifetime flows to the output
       |
    help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
       |
    27 |     pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<'_, str> {
       |                                                 +++

    warning: lifetime flowing from input to output with different syntax can be confusing
       --> serde_derive/src/internals/attr.rs:612:23
        |
    612 |     pub fn serde_path(&self) -> Cow<syn::Path> {
        |                       ^^^^^     -------------- the lifetime gets resolved as `'_`
        |                       |
        |                       this lifetime flows to the output
        |
        = note: `#[warn(mismatched_lifetime_syntaxes)]` on by default
    help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
        |
    612 |     pub fn serde_path(&self) -> Cow<'_, syn::Path> {
        |                                     +++

    warning: lifetime flowing from input to output with different syntax can be confusing
      --> serde_derive/src/internals/case.rs:45:37
       |
    45 |     pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
       |                                     ^^^^                  ---------- the lifetime gets resolved as `'_`
       |                                     |
       |                                     this lifetime flows to the output
       |
    help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
       |
    45 |     pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError<'_>> {
       |                                                                     ++++

    warning: lifetime flowing from input to output with different syntax can be confusing
        --> serde_derive/src/de.rs:3228:13
         |
    3228 |     params: &Parameters,
         |             ^^^^^^^^^^^ this lifetime flows to the output
    3229 | ) -> (
    3230 |     DeImplGenerics,
         |     -------------- the lifetimes get resolved as `'_`
    3231 |     DeTypeGenerics,
         |     -------------- the lifetimes get resolved as `'_`
    3232 |     syn::TypeGenerics,
         |     ----------------- the lifetimes get resolved as `'_`
    3233 |     Option<&syn::WhereClause>,
         |            ----------------- the lifetimes get resolved as `'_`
         |
    help: one option is to remove the lifetime for references and use the anonymous lifetime for paths
         |
    3230 ~     DeImplGenerics<'_>,
    3231 ~     DeTypeGenerics<'_>,
    3232 ~     syn::TypeGenerics<'_>,
         |
2025-06-05 22:11:48 -07:00
David Tolnay a1ddb18c92 Resolve new dead_code warnings in test suite
Bisects to https://github.com/rust-lang/rust/pull/141407.

    warning: struct `Struct` is never constructed
       --> test_suite/tests/test_gen.rs:803:16
        |
    803 |     pub struct Struct {
        |                ^^^^^^
        |
        = note: `#[warn(dead_code)]` on by default

    warning: function `vec_first_element` is never used
       --> test_suite/tests/test_gen.rs:885:4
        |
    885 | fn vec_first_element<T, S>(vec: &[T], serializer: S) -> StdResult<S::Ok, S::Error>
        |    ^^^^^^^^^^^^^^^^^

    warning: struct `S` is never constructed
     --> test_suite/tests/regression/issue2415.rs:5:12
      |
    5 | pub struct S;
      |            ^
      |
      = note: `#[warn(dead_code)]` on by default
2025-05-31 10:09:26 -07:00
David Tolnay da3998acfb Pin nightly toolchain used for miri job 2025-05-17 23:14:01 +02:00
Oli Scherer b9de3658ad Merge pull request #2919 from vishal-kr-barnwal/master
Update a Rust edition to 2021 across project files
2025-04-27 08:13:10 +00:00
Vishal Kumar 16af2d9ce7 Update a Rust edition to 2021 across project files
Updated the Cargo.toml files for test suites and a link in the README to use Rust edition 2021 instead of 2018. This ensures compatibility with the latest Rust features and standards.
2025-04-27 12:31:12 +05:30
David Tolnay b426ff81e3 Merge pull request #2913 from dtolnay/nightlywindows
Drop trailing whitespace from CI job name
2025-03-26 09:24:38 +00:00
David Tolnay b0e87aeecd Drop trailing whitespace from CI job name 2025-03-26 02:19:55 -07:00
David Tolnay a685dcf680 Merge pull request #2910 from jimmycathy/master
chore: fix the incorrect symbol
2025-03-16 00:05:43 -07:00
jimmycathy 88da17ca21 chore: fix the incorrect symbol
Signed-off-by: jimmycathy <clonecode@outlook.com>
2025-03-16 13:42:10 +08:00
David Tolnay d91f8ba950 Drop unused no_float_copysign cfg
Stable since Rust 1.35.
2025-03-09 12:39:05 -07:00
David Tolnay aa5aa611d4 Touch up PR 2901 2025-03-09 12:37:59 -07:00
David Tolnay da0b473d60 Merge pull request #2901 from serde-rs/msrv-and-edition-bump
MSRV (1.56) and edition (2021) bump
2025-03-09 15:37:44 -04:00
Oli Scherer 8b0e95b6de clippy 2025-03-05 10:07:07 +00:00
Oli Scherer e3a4165363 Switch all crates to edition 2021 2025-03-05 09:51:32 +00:00
Oli Scherer 6ac8049b92 clippy 2025-03-05 09:58:12 +00:00
Oli Scherer 13a33b3c33 Bump MSRV to 1.56
This is the first cargo version that actually enforces the rust-version field in Cargo.toml
2025-03-05 09:23:29 +00:00
71 changed files with 2025 additions and 871 deletions
+8 -14
View File
@@ -55,7 +55,7 @@ jobs:
- run: cd test_suite/no_std && cargo build
nightly:
name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}}
name: Rust nightly${{matrix.os == 'windows' && ' (windows)' || ''}}
runs-on: ${{matrix.os}}-latest
strategy:
fail-fast: false
@@ -70,7 +70,7 @@ jobs:
- run: cd serde && cargo build --no-default-features --features alloc
- run: cd serde && cargo build --no-default-features --features rc,alloc
- run: cd serde && cargo build --no-default-features --features unstable
- run: cd serde && cargo test --features derive,rc,unstable
- run: cd serde_core && cargo test --features rc,unstable
- run: cd test_suite/no_std && cargo build
if: matrix.os != 'windows'
- run: cd serde_derive && cargo check --tests
@@ -84,7 +84,7 @@ jobs:
strategy:
fail-fast: false
matrix:
rust: [1.31.0, 1.34.0]
rust: [1.56.0, 1.60.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
@@ -94,6 +94,7 @@ jobs:
- run: sed -i '/"test_suite"/d' Cargo.toml
- run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build --no-default-features --features alloc
- run: cd serde && cargo build
derive:
@@ -111,16 +112,6 @@ jobs:
- run: cd serde && cargo check
- run: cd serde_derive && cargo check
alloc:
name: Rust 1.36.0
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.36.0
- run: sed -i '/"test_suite"/d' Cargo.toml
- run: cd serde && cargo build --no-default-features --features alloc
minimal:
name: Minimal versions
runs-on: ubuntu-latest
@@ -154,6 +145,7 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@clippy
- run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_core && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic
@@ -166,8 +158,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@miri
with:
toolchain: nightly-2025-05-16 # https://github.com/rust-lang/miri/issues/4323
- run: cargo miri setup
- run: cd serde && cargo miri test --features derive,rc,unstable
- run: cd serde_core && cargo miri test --features rc,unstable
env:
MIRIFLAGS: -Zmiri-strict-provenance
- run: cd test_suite && cargo miri test --features unstable
+3
View File
@@ -1,13 +1,16 @@
[workspace]
members = [
"serde",
"serde_core",
"serde_derive",
"serde_derive_internals",
"test_suite",
]
resolver = "2"
[patch.crates-io]
serde = { path = "serde" }
serde_core = { path = "serde_core" }
[workspace.dependencies]
proc-macro2 = { version = "1.0.74", default-features = false }
+4 -4
View File
@@ -1,4 +1,4 @@
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.31] [![serde_derive msrv]][Rust 1.61]
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde msrv]][Rust 1.56] [![serde_derive msrv]][Rust 1.61]
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
@@ -6,7 +6,7 @@
[crates.io]: https://crates.io/crates/serde
[serde msrv]: https://img.shields.io/crates/msrv/serde.svg?label=serde%20msrv&color=lightgray
[serde_derive msrv]: https://img.shields.io/crates/msrv/serde_derive.svg?label=serde_derive%20msrv&color=lightgray
[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
[Rust 1.61]: https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
@@ -15,7 +15,7 @@
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [An overview of Serde](https://serde.rs)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
@@ -27,7 +27,7 @@ You may be looking for:
<details>
<summary>
Click to show Cargo.toml.
<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a>
<a href="https://play.rust-lang.org/?edition=2021&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a>
</summary>
```toml
+1 -1
View File
@@ -6,7 +6,7 @@
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [An overview of Serde](https://serde.rs)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
+8 -18
View File
@@ -1,25 +1,23 @@
[package]
name = "serde"
version = "1.0.219"
version = "1.0.221"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
description = "A generic serialization/deserialization framework"
documentation = "https://docs.rs/serde"
edition = "2018"
edition = "2021"
homepage = "https://serde.rs"
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.31"
rust-version = "1.56"
[dependencies]
serde_core = { version = "=1.0.221", path = "../serde_core", default-features = false, features = ["result"] }
serde_derive = { version = "1", optional = true, path = "../serde_derive" }
[dev-dependencies]
serde_derive = { version = "1", path = "../serde_derive" }
[package.metadata.playground]
features = ["derive", "rc"]
@@ -33,14 +31,6 @@ rustdoc-args = [
"--extern-html-root-url=std=https://doc.rust-lang.org",
]
# This cfg cannot be enabled, but it still forces Cargo to keep serde_derive's
# version in lockstep with serde's, even if someone depends on the two crates
# separately with serde's "derive" feature disabled. Every serde_derive release
# 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.219", path = "../serde_derive" }
### FEATURES #################################################################
@@ -52,20 +42,20 @@ derive = ["serde_derive"]
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
# Requires a dependency on the Rust standard library.
std = []
std = ["serde_core/std"]
# Provide impls for types that require unstable functionality. For tracking and
# discussion of unstable functionality please refer to this issue:
#
# https://github.com/serde-rs/serde/issues/812
unstable = []
unstable = ["serde_core/unstable"]
# Provide impls for types in the Rust core allocation and collections library
# including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
# be enabled without depending on all of std.
alloc = []
alloc = ["serde_core/alloc"]
# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
# does not preserve identity and may result in multiple copies of the same data.
# Be sure that this is what you want before enabling this feature.
rc = []
rc = ["serde_core/rc"]
-84
View File
@@ -14,97 +14,13 @@ fn main() {
};
if minor >= 77 {
println!("cargo:rustc-check-cfg=cfg(no_core_cstr)");
println!("cargo:rustc-check-cfg=cfg(no_core_error)");
println!("cargo:rustc-check-cfg=cfg(no_core_net)");
println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)");
println!("cargo:rustc-check-cfg=cfg(no_core_try_from)");
println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
println!("cargo:rustc-check-cfg=cfg(no_float_copysign)");
println!("cargo:rustc-check-cfg=cfg(no_num_nonzero_signed)");
println!("cargo:rustc-check-cfg=cfg(no_relaxed_trait_bounds)");
println!("cargo:rustc-check-cfg=cfg(no_serde_derive)");
println!("cargo:rustc-check-cfg=cfg(no_std_atomic)");
println!("cargo:rustc-check-cfg=cfg(no_std_atomic64)");
println!("cargo:rustc-check-cfg=cfg(no_systemtime_checked_add)");
println!("cargo:rustc-check-cfg=cfg(no_target_has_atomic)");
}
let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
// stabilized in Rust 1.34:
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
if minor < 34 {
println!("cargo:rustc-cfg=no_core_try_from");
println!("cargo:rustc-cfg=no_num_nonzero_signed");
println!("cargo:rustc-cfg=no_systemtime_checked_add");
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
}
// f32::copysign and f64::copysign stabilized in Rust 1.35.
// https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#copy-the-sign-of-a-floating-point-number-onto-another
if minor < 35 {
println!("cargo:rustc-cfg=no_float_copysign");
}
// Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
if minor < 60 {
println!("cargo:rustc-cfg=no_target_has_atomic");
// Allowlist of archs that support std::sync::atomic module. This is
// based on rustc's compiler/rustc_target/src/spec/*.rs.
let has_atomic64 = target.starts_with("x86_64")
|| target.starts_with("i686")
|| target.starts_with("aarch64")
|| target.starts_with("powerpc64")
|| target.starts_with("sparc64")
|| target.starts_with("mips64el")
|| target.starts_with("riscv64");
let has_atomic32 = has_atomic64 || emscripten;
if minor < 34 || !has_atomic64 {
println!("cargo:rustc-cfg=no_std_atomic64");
}
if minor < 34 || !has_atomic32 {
println!("cargo:rustc-cfg=no_std_atomic");
}
}
// Current minimum supported version of serde_derive crate is Rust 1.61.
if minor < 61 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64.
// https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc
if minor < 64 {
println!("cargo:rustc-cfg=no_core_cstr");
}
// Support for core::num::Saturating and std::num::Saturating stabilized in Rust 1.74
// https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html#stabilized-apis
if minor < 74 {
println!("cargo:rustc-cfg=no_core_num_saturating");
}
// Support for core::net stabilized in Rust 1.77.
// https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html
if minor < 77 {
println!("cargo:rustc-cfg=no_core_net");
}
// 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");
}
// The Error trait became available in core in 1.81.
// https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror
if minor < 81 {
println!("cargo:rustc-cfg=no_core_error");
}
}
fn rustc_minor_version() -> Option<u32> {
+7 -2
View File
@@ -1,6 +1,11 @@
// No longer used. Old versions of serde used this macro for supporting targets
// that did not yet have 128-bit integer support.
#[macro_export]
#[deprecated = "
This macro has no effect on any version of Serde released in the past 2 years.
It was used long ago in crates that needed to support Rustc older than 1.26.0,
or Emscripten targets older than 1.40.0, which did not yet have 128-bit integer
support. These days Serde requires a Rust compiler newer than that so 128-bit
integers are always supported.
"]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
($($tt:tt)*) => {
+18 -105
View File
@@ -9,7 +9,7 @@
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website <https://serde.rs/> for additional documentation and
//! See the Serde website <https://serde.rs> for additional documentation and
//! usage examples.
//!
//! ## Design
@@ -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.219")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.221")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
@@ -106,7 +106,12 @@
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![allow(
unknown_lints,
bare_trait_objects,
deprecated,
mismatched_lifetime_syntaxes
)]
// Ignored clippy and clippy_pedantic lints
#![allow(
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
@@ -175,25 +180,18 @@ mod lib {
}
pub use self::core::{f32, f64};
pub use self::core::{i16, i32, i64, i8, isize};
pub use self::core::{iter, num, ptr, str};
pub use self::core::{u16, u32, u64, u8, usize};
pub use self::core::{ptr, str};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::core::{cmp, mem, slice};
pub use self::core::slice;
pub use self::core::cell::{Cell, RefCell};
pub use self::core::clone;
pub use self::core::cmp::Reverse;
pub use self::core::convert;
pub use self::core::default;
pub use self::core::fmt::{self, Debug, Display, Write as FmtWrite};
pub use self::core::marker::{self, PhantomData};
pub use self::core::num::Wrapping;
pub use self::core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo};
pub use self::core::option;
pub use self::core::result;
pub use self::core::time::Duration;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::borrow::{Cow, ToOwned};
@@ -214,84 +212,13 @@ mod lib {
pub use alloc::boxed::Box;
#[cfg(feature = "std")]
pub use std::boxed::Box;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(all(not(no_core_cstr), not(feature = "std")))]
pub use self::core::ffi::CStr;
#[cfg(feature = "std")]
pub use std::ffi::CStr;
#[cfg(all(not(no_core_cstr), feature = "alloc", not(feature = "std")))]
pub use alloc::ffi::CString;
#[cfg(feature = "std")]
pub use std::ffi::CString;
#[cfg(all(not(no_core_net), not(feature = "std")))]
pub use self::core::net;
#[cfg(feature = "std")]
pub use std::net;
#[cfg(feature = "std")]
pub use std::error;
#[cfg(feature = "std")]
pub use std::collections::{HashMap, HashSet};
#[cfg(feature = "std")]
pub use std::ffi::{OsStr, OsString};
#[cfg(feature = "std")]
pub use std::hash::{BuildHasher, Hash};
#[cfg(feature = "std")]
pub use std::io::Write;
#[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
AtomicUsize, Ordering,
};
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))]
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(not(no_core_num_saturating))]
pub use self::core::num::Saturating;
}
// 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 `?`.
#[cfg(not(no_serde_derive))]
macro_rules! tri {
($expr:expr) => {
match $expr {
@@ -303,33 +230,18 @@ macro_rules! tri {
////////////////////////////////////////////////////////////////////////////////
#[macro_use]
mod macros;
pub use serde_core::{
de, forward_to_deserialize_any, ser, Deserialize, Deserializer, Serialize, Serializer,
};
#[macro_use]
mod integer128;
pub mod de;
pub mod ser;
mod format;
#[doc(inline)]
pub use crate::de::{Deserialize, Deserializer};
#[doc(inline)]
pub use crate::ser::{Serialize, Serializer};
// Used by generated code and doc tests. Not public API.
#[doc(hidden)]
#[path = "private/mod.rs"]
pub mod __private;
#[path = "de/seed.rs"]
mod seed;
#[cfg(all(not(feature = "std"), no_core_error))]
mod std_error;
// Re-export #[derive(Serialize, Deserialize)].
//
// The reason re-exporting is not enabled by default is that disabling it would
@@ -343,7 +255,8 @@ extern crate serde_derive;
#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
pub use serde_derive::{Deserialize, Serialize};
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
mod actually_private {
pub struct T;
#[macro_export]
#[doc(hidden)]
macro_rules! __require_serde_not_serde_core {
() => {};
}
+751 -358
View File
File diff suppressed because it is too large Load Diff
+2 -32
View File
@@ -3,11 +3,8 @@ pub mod de;
#[cfg(not(no_serde_derive))]
pub mod ser;
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
pub mod doc;
pub use crate::lib::clone::Clone;
pub use crate::lib::convert::{From, Into};
pub use crate::lib::convert::{From, Into, TryFrom};
pub use crate::lib::default::Default;
pub use crate::lib::fmt::{self, Formatter};
pub use crate::lib::marker::PhantomData;
@@ -15,34 +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 self::string::from_utf8_lossy;
pub use serde_core::__private::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))]
pub use crate::lib::{ToString, Vec};
#[cfg(not(no_core_try_from))]
pub use crate::lib::convert::TryFrom;
mod string {
use crate::lib::*;
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
//
// let value = &_serde::__private::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "std", feature = "alloc")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
}
}
+69
View File
@@ -0,0 +1,69 @@
[package]
name = "serde_core"
version = "1.0.221"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
description = "Serde traits only, with no support for derive -- use the `serde` crate instead"
documentation = "https://docs.rs/serde_core"
edition = "2021"
homepage = "https://serde.rs"
keywords = ["serde", "serialization", "no_std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
[dev-dependencies]
serde = { version = "1", path = "../serde" }
serde_derive = { version = "1", path = "../serde_derive" }
[package.metadata.playground]
features = ["rc", "result"]
[package.metadata.docs.rs]
features = ["rc", "result", "unstable"]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = [
"--generate-link-to-definition",
"--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",
]
# This cfg cannot be enabled, but it still forces Cargo to keep serde_derive's
# version in lockstep with serde's, even if someone depends on the two crates
# separately with serde's "derive" feature disabled. Every serde_derive release
# 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.221", path = "../serde_derive" }
### FEATURES #################################################################
[features]
default = ["std", "result"]
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
# Requires a dependency on the Rust standard library.
std = []
# Provide impls for types that require unstable functionality. For tracking and
# discussion of unstable functionality please refer to this issue:
#
# https://github.com/serde-rs/serde/issues/812
unstable = []
# Provide impls for types in the Rust core allocation and collections library
# including String, Box<T>, Vec<T>, and Cow<T>. This is a subset of std but may
# be enabled without depending on all of std.
alloc = []
# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
# does not preserve identity and may result in multiple copies of the same data.
# Be sure that this is what you want before enabling this feature.
rc = []
# Provide impls for Result<T, E>. Convenient in some contexts but can lead to
# confusion if ? or unwrap are used incautiously.
result = []
+1
View File
@@ -0,0 +1 @@
../LICENSE-APACHE
+1
View File
@@ -0,0 +1 @@
../LICENSE-MIT
+28
View File
@@ -0,0 +1,28 @@
The `serde_core` crate contains Serde's trait definitions with **no support for
#\[derive()\]**.
In crates that derive an implementation of `Serialize` or `Deserialize`, you
must depend on the [`serde`] crate, not `serde_core`.
[`serde`]: https://crates.io/crates/serde
In crates that handwrite implementations of Serde traits, or only use them as
trait bounds, depending on `serde_core` is permitted. But `serde` re-exports all
of these traits and can be used for this use case too. If in doubt, disregard
`serde_core` and always use `serde`.
Crates that depend on `serde_core` instead of `serde` are able to compile in
parallel with `serde_derive` even when `serde`'s "derive" feature is turned on,
as shown in the following build timings.
<br>
| When `serde_json` depends on `serde` |
|---|
| <img src="https://github.com/user-attachments/assets/78dc179c-6ab1-4059-928c-1474b0d9d0bb"> |
<br>
| When `serde_json` depends on `serde_core` |
|---|
| <img src="https://github.com/user-attachments/assets/6b6cff5e-3e45-4ac7-9db1-d99ee8b9f5f7"> |
+97
View File
@@ -0,0 +1,97 @@
use std::env;
use std::process::Command;
use std::str;
// 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 minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
if minor >= 77 {
println!("cargo:rustc-check-cfg=cfg(no_core_cstr)");
println!("cargo:rustc-check-cfg=cfg(no_core_error)");
println!("cargo:rustc-check-cfg=cfg(no_core_net)");
println!("cargo:rustc-check-cfg=cfg(no_core_num_saturating)");
println!("cargo:rustc-check-cfg=cfg(no_diagnostic_namespace)");
println!("cargo:rustc-check-cfg=cfg(no_serde_derive)");
println!("cargo:rustc-check-cfg=cfg(no_std_atomic)");
println!("cargo:rustc-check-cfg=cfg(no_std_atomic64)");
println!("cargo:rustc-check-cfg=cfg(no_target_has_atomic)");
}
let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
// Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
if minor < 60 {
println!("cargo:rustc-cfg=no_target_has_atomic");
// Allowlist of archs that support std::sync::atomic module. This is
// based on rustc's compiler/rustc_target/src/spec/*.rs.
let has_atomic64 = target.starts_with("x86_64")
|| target.starts_with("i686")
|| target.starts_with("aarch64")
|| target.starts_with("powerpc64")
|| target.starts_with("sparc64")
|| target.starts_with("mips64el")
|| target.starts_with("riscv64");
let has_atomic32 = has_atomic64 || emscripten;
if minor < 34 || !has_atomic64 {
println!("cargo:rustc-cfg=no_std_atomic64");
}
if minor < 34 || !has_atomic32 {
println!("cargo:rustc-cfg=no_std_atomic");
}
}
// Current minimum supported version of serde_derive crate is Rust 1.61.
if minor < 61 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64.
// https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc
if minor < 64 {
println!("cargo:rustc-cfg=no_core_cstr");
}
// Support for core::num::Saturating and std::num::Saturating stabilized in Rust 1.74
// https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html#stabilized-apis
if minor < 74 {
println!("cargo:rustc-cfg=no_core_num_saturating");
}
// Support for core::net stabilized in Rust 1.77.
// https://blog.rust-lang.org/2024/03/21/Rust-1.77.0.html
if minor < 77 {
println!("cargo:rustc-cfg=no_core_net");
}
// 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");
}
// The Error trait became available in core in 1.81.
// https://blog.rust-lang.org/2024/09/05/Rust-1.81.0.html#coreerrorerror
if minor < 81 {
println!("cargo:rustc-cfg=no_core_error");
}
}
fn rustc_minor_version() -> Option<u32> {
let rustc = env::var_os("RUSTC")?;
let output = Command::new(rustc).arg("--version").output().ok()?;
let version = str::from_utf8(&output.stdout).ok()?;
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
pieces.next()?.parse().ok()
}
@@ -4,11 +4,10 @@ use crate::de::{
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, Unexpected, VariantAccess,
Visitor,
};
use crate::seed::InPlaceSeed;
use crate::private::{self, InPlaceSeed};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::de::size_hint;
use crate::private::size_hint;
////////////////////////////////////////////////////////////////////////////////
@@ -80,10 +79,9 @@ impl<'de> Deserialize<'de> for bool {
////////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num {
($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
($primitive:ident, $nonzero:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
$(#[cfg($($cfg)*)])*
impl<'de> Deserialize<'de> for num::$nonzero {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -228,12 +226,12 @@ macro_rules! num_as_copysign_self {
where
E: Error,
{
#[cfg(any(no_float_copysign, not(feature = "std")))]
#[cfg(not(feature = "std"))]
{
Ok(v as Self::Value)
}
#[cfg(all(not(no_float_copysign), feature = "std"))]
#[cfg(feature = "std")]
{
// Preserve sign of NaN. The `as` produces a nondeterministic sign.
let sign = if v.is_sign_positive() { 1.0 } else { -1.0 };
@@ -250,13 +248,8 @@ macro_rules! int_to_int {
where
E: Error,
{
if Self::Value::min_value() as i64 <= v as i64
&& v as i64 <= Self::Value::max_value() as i64
{
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
}
Self::Value::try_from(v as i64)
.map_err(|_| Error::invalid_value(Unexpected::Signed(v as i64), &self))
}
};
@@ -265,10 +258,8 @@ macro_rules! int_to_int {
where
E: Error,
{
if $primitive::min_value() as i64 <= v as i64
&& v as i64 <= $primitive::max_value() as i64
{
if let Some(nonzero) = Self::Value::new(v as $primitive) {
if let Ok(v) = $primitive::try_from(v as i64) {
if let Some(nonzero) = Self::Value::new(v) {
return Ok(nonzero);
}
}
@@ -299,11 +290,13 @@ macro_rules! int_to_uint {
where
E: Error,
{
if 0 <= v && v as u64 <= Self::Value::max_value() as u64 {
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
if 0 <= v {
#[allow(irrefutable_let_patterns)]
if let Ok(v) = Self::Value::try_from(v as u64) {
return Ok(v as Self::Value);
}
}
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
}
};
@@ -312,9 +305,12 @@ macro_rules! int_to_uint {
where
E: Error,
{
if 0 < v && v as u64 <= $primitive::max_value() as u64 {
if let Some(nonzero) = Self::Value::new(v as $primitive) {
return Ok(nonzero);
if 0 < v {
#[allow(irrefutable_let_patterns)]
if let Ok(v) = $primitive::try_from(v as u64) {
if let Some(nonzero) = Self::Value::new(v) {
return Ok(nonzero);
}
}
}
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
@@ -344,11 +340,8 @@ macro_rules! uint_to_self {
where
E: Error,
{
if v as u64 <= Self::Value::max_value() as u64 {
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
}
Self::Value::try_from(v as u64)
.map_err(|_| Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
}
};
@@ -357,8 +350,8 @@ macro_rules! uint_to_self {
where
E: Error,
{
if v as u64 <= $primitive::max_value() as u64 {
if let Some(nonzero) = Self::Value::new(v as $primitive) {
if let Ok(v) = $primitive::try_from(v as u64) {
if let Some(nonzero) = Self::Value::new(v) {
return Ok(nonzero);
}
}
@@ -371,7 +364,7 @@ macro_rules! uint_to_self {
where
E: Error,
{
if v as u64 <= $primitive::MAX as u64 {
if let Ok(v) = $primitive::try_from(v as u64) {
Ok(Saturating(v as $primitive))
} else {
Ok(Saturating($primitive::MAX))
@@ -381,14 +374,14 @@ macro_rules! uint_to_self {
}
impl_deserialize_num! {
i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), deserialize_i8
i8, NonZeroI8, deserialize_i8
num_self!(i8:visit_i8);
int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
}
impl_deserialize_num! {
i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16
i16, NonZeroI16, deserialize_i16
num_self!(i16:visit_i16);
num_as_self!(i8:visit_i8);
int_to_int!(i32:visit_i32 i64:visit_i64);
@@ -396,7 +389,7 @@ impl_deserialize_num! {
}
impl_deserialize_num! {
i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32
i32, NonZeroI32, deserialize_i32
num_self!(i32:visit_i32);
num_as_self!(i8:visit_i8 i16:visit_i16);
int_to_int!(i64:visit_i64);
@@ -404,14 +397,14 @@ impl_deserialize_num! {
}
impl_deserialize_num! {
i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), deserialize_i64
i64, NonZeroI64, deserialize_i64
num_self!(i64:visit_i64);
num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
}
impl_deserialize_num! {
isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), deserialize_i64
isize, NonZeroIsize, deserialize_i64
num_as_self!(i8:visit_i8 i16:visit_i16);
int_to_int!(i32:visit_i32 i64:visit_i64);
uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
@@ -476,9 +469,7 @@ macro_rules! num_128 {
where
E: Error,
{
if v as i128 >= Self::Value::min_value() as i128
&& v as u128 <= Self::Value::max_value() as u128
{
if v as i128 >= Self::Value::MIN as i128 && v as u128 <= Self::Value::MAX as u128 {
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(
@@ -494,9 +485,7 @@ macro_rules! num_128 {
where
E: Error,
{
if v as i128 >= $primitive::min_value() as i128
&& v as u128 <= $primitive::max_value() as u128
{
if v as i128 >= $primitive::MIN as i128 && v as u128 <= $primitive::MAX as u128 {
if let Some(nonzero) = Self::Value::new(v as $primitive) {
Ok(nonzero)
} else {
@@ -528,7 +517,7 @@ macro_rules! num_128 {
}
impl_deserialize_num! {
i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), deserialize_i128
i128, NonZeroI128, deserialize_i128
num_self!(i128:visit_i128);
num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
@@ -2184,7 +2173,7 @@ impl<'de> Deserialize<'de> for Duration {
b"secs" => Ok(Field::Secs),
b"nanos" => Ok(Field::Nanos),
_ => {
let value = crate::__private::from_utf8_lossy(value);
let value = private::string::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
@@ -2415,13 +2404,9 @@ impl<'de> Deserialize<'de> for SystemTime {
const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"];
let duration = tri!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
#[cfg(not(no_systemtime_checked_add))]
let ret = UNIX_EPOCH
UNIX_EPOCH
.checked_add(duration)
.ok_or_else(|| D::Error::custom("overflow deserializing SystemTime"));
#[cfg(no_systemtime_checked_add)]
let ret = Ok(UNIX_EPOCH + duration);
ret
.ok_or_else(|| D::Error::custom("overflow deserializing SystemTime"))
}
}
@@ -2479,6 +2464,7 @@ mod range {
use crate::lib::*;
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
use crate::private;
pub const FIELDS: &[&str] = &["start", "end"];
@@ -2524,7 +2510,7 @@ mod range {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = crate::__private::from_utf8_lossy(value);
let value = private::string::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
@@ -2637,6 +2623,7 @@ mod range_from {
use crate::lib::*;
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
use crate::private;
pub const FIELDS: &[&str] = &["start"];
@@ -2679,7 +2666,7 @@ mod range_from {
match value {
b"start" => Ok(Field::Start),
_ => {
let value = crate::__private::from_utf8_lossy(value);
let value = private::string::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
@@ -2775,6 +2762,7 @@ mod range_to {
use crate::lib::*;
use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
use crate::private;
pub const FIELDS: &[&str] = &["end"];
@@ -2817,7 +2805,7 @@ mod range_to {
match value {
b"end" => Ok(Field::End),
_ => {
let value = crate::__private::from_utf8_lossy(value);
let value = private::string::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS))
}
}
@@ -2989,6 +2977,8 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "result")]
#[cfg_attr(docsrs, doc(cfg(feature = "result")))]
impl<'de, T, E> Deserialize<'de> for Result<T, E>
where
T: Deserialize<'de>,
@@ -120,10 +120,9 @@ pub mod value;
mod ignored_any;
mod impls;
pub(crate) mod size_hint;
pub use self::ignored_any::IgnoredAny;
pub use crate::private::InPlaceSeed;
#[cfg(all(not(feature = "std"), no_core_error))]
#[doc(no_inline)]
pub use crate::std_error::Error as StdError;
@@ -158,6 +157,12 @@ macro_rules! declare_error_trait {
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::Error` is not satisfied",
)
)]
pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Raised when there is general error when deserializing a type.
///
@@ -206,7 +211,7 @@ macro_rules! declare_error_trait {
/// containing an integer, the unexpected type is the integer and the
/// expected type is the string.
#[cold]
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
fn invalid_type(unexp: Unexpected, exp: &dyn Expected) -> Self {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
}
@@ -224,7 +229,7 @@ macro_rules! declare_error_trait {
/// that is not valid UTF-8, the unexpected value is the bytes and the
/// expected value is a string.
#[cold]
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
fn invalid_value(unexp: Unexpected, exp: &dyn Expected) -> Self {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
}
@@ -238,7 +243,7 @@ macro_rules! declare_error_trait {
/// expected. For example `exp` might say that a tuple of size 6 was
/// expected.
#[cold]
fn invalid_length(len: usize, exp: &Expected) -> Self {
fn invalid_length(len: usize, exp: &dyn Expected) -> Self {
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
}
@@ -471,6 +476,12 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// ));
/// # }
/// ```
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::Expected` is not satisfied",
)
)]
pub trait Expected {
/// Format an explanation of what data was being expected. Same signature as
/// the `Display` and `Debug` traits.
@@ -492,7 +503,7 @@ impl Expected for &str {
}
}
impl Display for Expected + '_ {
impl Display for dyn Expected + '_ {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Expected::fmt(self, formatter)
}
@@ -534,6 +545,9 @@ impl Display for Expected + '_ {
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
// Prevents `serde_core::de::Deserialize` appearing in the error message
// in projects with no direct dependency on serde_core.
message = "the trait bound `{Self}: serde::Deserialize<'de>` is not satisfied",
note = "for local types consider adding `#[derive(serde::Deserialize)]` to your `{Self}` type",
note = "for types from other crates check whether the crate offers a `serde` feature flag",
)
@@ -610,6 +624,12 @@ pub trait Deserialize<'de>: Sized {
/// lifetimes].
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::DeserializeOwned` is not satisfied",
)
)]
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
@@ -775,6 +795,12 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// # Ok(())
/// # }
/// ```
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::DeserializeSeed<'de>` is not satisfied",
)
)]
pub trait DeserializeSeed<'de>: Sized {
/// The type produced by using this seed.
type Value;
@@ -911,6 +937,12 @@ where
/// a basic JSON `Deserializer`.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::Deserializer<'de>` is not satisfied",
)
)]
pub trait Deserializer<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1226,13 +1258,9 @@ pub trait Deserializer<'de>: Sized {
// Not public API.
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
fn __deserialize_content<V>(
self,
_: crate::actually_private::T,
visitor: V,
) -> Result<crate::__private::de::Content<'de>, Self::Error>
fn __deserialize_content_v1<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de, Value = crate::__private::de::Content<'de>>,
V: Visitor<'de, Value = crate::private::Content<'de>>,
{
self.deserialize_any(visitor)
}
@@ -1281,6 +1309,12 @@ pub trait Deserializer<'de>: Sized {
/// }
/// }
/// ```
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::Visitor<'de>` is not satisfied",
)
)]
pub trait Visitor<'de>: Sized {
/// The value produced by this visitor.
type Value;
@@ -1707,6 +1741,12 @@ pub trait Visitor<'de>: Sized {
/// implementation of `SeqAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::SeqAccess<'de>` is not satisfied",
)
)]
pub trait SeqAccess<'de> {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1789,6 +1829,12 @@ where
/// implementation of `MapAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::MapAccess<'de>` is not satisfied",
)
)]
pub trait MapAccess<'de> {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1981,6 +2027,12 @@ where
/// implementation of `EnumAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::EnumAccess<'de>` is not satisfied",
)
)]
pub trait EnumAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -2028,6 +2080,12 @@ pub trait EnumAccess<'de>: Sized {
/// implementation of `VariantAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::de::VariantAccess<'de>` is not satisfied",
)
)]
pub trait VariantAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization. Must match the error type of our `EnumAccess`.
@@ -24,7 +24,8 @@
use crate::lib::*;
use self::private::{First, Second};
use crate::de::{self, size_hint, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
use crate::de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
use crate::private::size_hint;
use crate::ser;
////////////////////////////////////////////////////////////////////////////////
+270
View File
@@ -0,0 +1,270 @@
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The `serde_core` crate contains Serde's trait definitions with **no support
//! for #\[derive()\]**.
//!
//! In crates that derive an implementation of `Serialize` or `Deserialize`, you
//! must depend on the [`serde`] crate, not `serde_core`.
//!
//! [`serde`]: https://crates.io/crates/serde
//!
//! In crates that handwrite implementations of Serde traits, or only use them
//! as trait bounds, depending on `serde_core` is permitted. But `serde`
//! re-exports all of these traits and can be used for this use case too. If in
//! doubt, disregard `serde_core` and always use `serde`.
//!
//! Crates that depend on `serde_core` instead of `serde` are able to compile in
//! parallel with `serde_derive` even when `serde`'s "derive" feature is turned on,
//! as shown in the following build timings.
//!
//! <br>
//!
//! <table>
//! <tr><td align="center">When <code>serde_json</code> depends on <code>serde</code></td></tr>
//! <tr><td><img src="https://github.com/user-attachments/assets/78dc179c-6ab1-4059-928c-1474b0d9d0bb"></td></tr>
//! </table>
//!
//! <br>
//!
//! <table>
//! <tr><td align="center">When <code>serde_json</code> depends on <code>serde_core</code></td></tr>
//! <tr><td><img src="https://github.com/user-attachments/assets/6b6cff5e-3e45-4ac7-9db1-d99ee8b9f5f7"></td></tr>
//! </table>
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.221")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Show which crate feature enables conditionally compiled APIs in documentation.
#![cfg_attr(docsrs, feature(doc_cfg, rustdoc_internals))]
#![cfg_attr(docsrs, allow(internal_features))]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
// Ignored clippy and clippy_pedantic lints
#![allow(
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
clippy::unnested_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
clippy::semicolon_if_nothing_returned,
// not available in our oldest supported compiler
clippy::empty_enum,
clippy::type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
// integer and float ser/de requires these sorts of casts
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_precision_loss,
clippy::cast_sign_loss,
// things are often more readable this way
clippy::cast_lossless,
clippy::module_name_repetitions,
clippy::single_match_else,
clippy::type_complexity,
clippy::use_self,
clippy::zero_prefixed_literal,
// correctly used
clippy::derive_partial_eq_without_eq,
clippy::enum_glob_use,
clippy::explicit_auto_deref,
clippy::incompatible_msrv,
clippy::let_underscore_untyped,
clippy::map_err_ignore,
clippy::new_without_default,
clippy::result_unit_err,
clippy::wildcard_imports,
// not practical
clippy::needless_pass_by_value,
clippy::similar_names,
clippy::too_many_lines,
// preference
clippy::doc_markdown,
clippy::elidable_lifetime_names,
clippy::needless_lifetimes,
clippy::unseparated_literal_suffix,
// false positive
clippy::needless_doctest_main,
// noisy
clippy::missing_errors_doc,
clippy::must_use_candidate,
)]
// Restrictions
#![deny(clippy::question_mark_used)]
// Rustc lints.
#![deny(missing_docs, unused_imports)]
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "alloc")]
extern crate alloc;
/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
mod core {
#[cfg(not(feature = "std"))]
pub use core::*;
#[cfg(feature = "std")]
pub use std::*;
}
pub use self::core::{f32, f64};
pub use self::core::{iter, num, str};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::core::{cmp, mem};
pub use self::core::cell::{Cell, RefCell};
pub use self::core::cmp::Reverse;
pub use self::core::fmt::{self, Debug, Display, Write as FmtWrite};
pub use self::core::marker::PhantomData;
pub use self::core::num::Wrapping;
pub use self::core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo};
pub use self::core::result;
pub use self::core::time::Duration;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::borrow::{Cow, ToOwned};
#[cfg(feature = "std")]
pub use std::borrow::{Cow, ToOwned};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::string::{String, ToString};
#[cfg(feature = "std")]
pub use std::string::{String, ToString};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::vec::Vec;
#[cfg(feature = "std")]
pub use std::vec::Vec;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::boxed::Box;
#[cfg(feature = "std")]
pub use std::boxed::Box;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(all(not(no_core_cstr), not(feature = "std")))]
pub use self::core::ffi::CStr;
#[cfg(feature = "std")]
pub use std::ffi::CStr;
#[cfg(all(not(no_core_cstr), feature = "alloc", not(feature = "std")))]
pub use alloc::ffi::CString;
#[cfg(feature = "std")]
pub use std::ffi::CString;
#[cfg(all(not(no_core_net), not(feature = "std")))]
pub use self::core::net;
#[cfg(feature = "std")]
pub use std::net;
#[cfg(feature = "std")]
pub use std::error;
#[cfg(feature = "std")]
pub use std::collections::{HashMap, HashSet};
#[cfg(feature = "std")]
pub use std::ffi::{OsStr, OsString};
#[cfg(feature = "std")]
pub use std::hash::{BuildHasher, Hash};
#[cfg(feature = "std")]
pub use std::io::Write;
#[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
AtomicUsize, Ordering,
};
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))]
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(not(no_core_num_saturating))]
pub use self::core::num::Saturating;
}
// 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! tri {
($expr:expr) => {
match $expr {
Ok(val) => val,
Err(err) => return Err(err),
}
};
}
////////////////////////////////////////////////////////////////////////////////
#[macro_use]
mod macros;
pub mod de;
pub mod ser;
mod format;
#[doc(inline)]
pub use crate::de::{Deserialize, Deserializer};
#[doc(inline)]
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;
#[cfg(all(not(feature = "std"), no_core_error))]
mod std_error;
#[macro_export]
#[doc(hidden)]
macro_rules! __require_serde_not_serde_core {
() => {
::core::compile_error!(
"Serde derive requires a dependency on the serde crate, not serde_core"
);
};
}
@@ -1,7 +1,6 @@
// Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize
// documentation.
//
/// Helper macro when implementing the `Deserializer` part of a new data format
/// for Serde.
///
+264
View File
@@ -0,0 +1,264 @@
use crate::de::{self, Deserialize, Deserializer, EnumAccess, MapAccess, SeqAccess, Visitor};
use crate::lib::*;
use crate::private::size_hint;
// Used from generated code to buffer the contents of the Deserializer when
// deserializing untagged enums and internally tagged enums.
//
// Not public API. Use serde-value instead.
//
// Obsoleted by format-specific buffer types (https://github.com/serde-rs/serde/pull/2912).
#[derive(Clone)]
#[doc(hidden)]
pub enum Content<'de> {
Bool(bool),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
I8(i8),
I16(i16),
I32(i32),
I64(i64),
F32(f32),
F64(f64),
Char(char),
String(String),
Str(&'de str),
ByteBuf(Vec<u8>),
Bytes(&'de [u8]),
None,
Some(Box<Content<'de>>),
Unit,
Newtype(Box<Content<'de>>),
Seq(Vec<Content<'de>>),
Map(Vec<(Content<'de>, Content<'de>)>),
}
impl<'de> Deserialize<'de> for Content<'de> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Untagged and internally tagged enums are only supported in
// self-describing formats.
let visitor = ContentVisitor { value: PhantomData };
deserializer.__deserialize_content_v1(visitor)
}
}
#[doc(hidden)]
pub struct ContentVisitor<'de> {
value: PhantomData<Content<'de>>,
}
impl<'de> ContentVisitor<'de> {
pub fn new() -> Self {
ContentVisitor { value: PhantomData }
}
}
impl<'de> Visitor<'de> for ContentVisitor<'de> {
type Value = Content<'de>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("any value")
}
fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bool(value))
}
fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I8(value))
}
fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I16(value))
}
fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I32(value))
}
fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::I64(value))
}
fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U8(value))
}
fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U16(value))
}
fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U32(value))
}
fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::U64(value))
}
fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F32(value))
}
fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::F64(value))
}
fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Char(value))
}
fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value.into()))
}
fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Str(value))
}
fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::String(value))
}
fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value.into()))
}
fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Bytes(value))
}
fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::ByteBuf(value))
}
fn visit_unit<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::Unit)
}
fn visit_none<F>(self) -> Result<Self::Value, F>
where
F: de::Error,
{
Ok(Content::None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Some(Box::new(v)))
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let v = tri!(Deserialize::deserialize(deserializer));
Ok(Content::Newtype(Box::new(v)))
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut vec =
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
while let Some(e) = tri!(visitor.next_element()) {
vec.push(e);
}
Ok(Content::Seq(vec))
}
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: MapAccess<'de>,
{
let mut vec = Vec::<(Content, Content)>::with_capacity(size_hint::cautious::<(
Content,
Content,
)>(visitor.size_hint()));
while let Some(kv) = tri!(visitor.next_entry()) {
vec.push(kv);
}
Ok(Content::Map(vec))
}
fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error>
where
V: EnumAccess<'de>,
{
Err(de::Error::custom(
"untagged and internally tagged enums do not support enum input",
))
}
}
+21
View File
@@ -0,0 +1,21 @@
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
mod content;
mod seed;
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
#[doc(hidden)]
pub mod doc;
#[doc(hidden)]
pub mod size_hint;
#[doc(hidden)]
pub mod string;
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
pub use self::content::{Content, ContentVisitor};
#[doc(hidden)]
pub use self::seed::InPlaceSeed;
#[doc(hidden)]
pub use crate::lib::result::Result;
@@ -1,3 +1,4 @@
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::lib::*;
pub fn from_bounds<I>(iter: &I) -> Option<usize>
+23
View File
@@ -0,0 +1,23 @@
use crate::lib::*;
#[cfg(any(feature = "std", feature = "alloc"))]
#[doc(hidden)]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<'_, str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
//
// let value = &_serde::__private::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
}
@@ -185,11 +185,10 @@ where
}
}
#[cfg(not(no_relaxed_trait_bounds))]
macro_rules! seq_impl {
(
$(#[$attr:meta])*
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>
$ty:ident <T $(, $typaram:ident : $bound:ident)*>
) => {
$(#[$attr])*
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
@@ -207,45 +206,22 @@ macro_rules! seq_impl {
}
}
#[cfg(no_relaxed_trait_bounds)]
macro_rules! seq_impl {
(
$(#[$attr:meta])*
$ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>
) => {
$(#[$attr])*
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
where
T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
$($typaram: $bound,)*
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(self)
}
}
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BinaryHeap<T>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BinaryHeap<T: Ord>
}
seq_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
BTreeSet<T: Ord>
BTreeSet<T>
}
seq_impl! {
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
HashSet<T: Eq + Hash, H: BuildHasher>
HashSet<T, H: BuildHasher>
}
seq_impl! {
@@ -445,7 +421,6 @@ tuple_impls! {
////////////////////////////////////////////////////////////////////////////////
#[cfg(not(no_relaxed_trait_bounds))]
macro_rules! map_impl {
(
$(#[$attr:meta])*
@@ -468,30 +443,6 @@ macro_rules! map_impl {
}
}
#[cfg(no_relaxed_trait_bounds)]
macro_rules! map_impl {
(
$(#[$attr:meta])*
$ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>
) => {
$(#[$attr])*
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where
K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
V: Serialize,
$($typaram: $bound,)*
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_map(self)
}
}
}
}
map_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg_attr(docsrs, doc(cfg(any(feature = "std", feature = "alloc"))))]
@@ -631,16 +582,6 @@ macro_rules! nonzero_integers {
}
}
nonzero_integers! {
NonZeroU8,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU128,
NonZeroUsize,
}
#[cfg(not(no_num_nonzero_signed))]
nonzero_integers! {
NonZeroI8,
NonZeroI16,
@@ -648,6 +589,12 @@ nonzero_integers! {
NonZeroI64,
NonZeroI128,
NonZeroIsize,
NonZeroU8,
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU128,
NonZeroUsize,
}
impl<T> Serialize for Cell<T>
@@ -713,6 +660,8 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "result")]
#[cfg_attr(docsrs, doc(cfg(feature = "result")))]
impl<T, E> Serialize for Result<T, E>
where
T: Serialize,
@@ -17,7 +17,7 @@ use crate::ser::{
///
/// ```edition2021
/// # use serde::ser::{Serializer, Impossible};
/// # use serde::__private::doc::Error;
/// # use serde_core::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
@@ -41,7 +41,7 @@ use crate::ser::{
/// }
///
/// /* other Serializer methods */
/// # serde::__serialize_unimplemented! {
/// # serde_core::__serialize_unimplemented! {
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant
/// # tuple tuple_struct tuple_variant map struct struct_variant
@@ -139,6 +139,12 @@ macro_rules! declare_error_trait {
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::Error` is not satisfied",
)
)]
pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Used when a [`Serialize`] implementation encounters any error
/// while serializing a type.
@@ -218,6 +224,9 @@ declare_error_trait!(Error: Sized + Debug + Display);
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
// Prevents `serde_core::ser::Serialize` appearing in the error message
// in projects with no direct dependency on serde_core.
message = "the trait bound `{Self}: serde::Serialize` is not satisfied",
note = "for local types consider adding `#[derive(serde::Serialize)]` to your `{Self}` type",
note = "for types from other crates check whether the crate offers a `serde` feature flag",
)
@@ -337,6 +346,12 @@ pub trait Serialize {
/// a basic JSON `Serializer`.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::Serializer` is not satisfied",
)
)]
pub trait Serializer: Sized {
/// The output type produced by this `Serializer` during successful
/// serialization. Most serializers that produce text or binary output
@@ -398,7 +413,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for bool {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -420,7 +435,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for i8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -442,7 +457,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for i16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -464,7 +479,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for i32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -482,7 +497,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for i64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -500,7 +515,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for i128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -527,7 +542,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for u8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -549,7 +564,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for u16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -571,7 +586,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for u32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -589,7 +604,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for u64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -607,7 +622,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for u128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -634,7 +649,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for f32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -652,7 +667,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for f64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -673,7 +688,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for char {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -691,7 +706,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for str {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -714,7 +729,7 @@ pub trait Serializer: Sized {
///
/// ```edition2021
/// # use serde::ser::{Serializer, SerializeSeq};
/// # use serde::__private::doc::Error;
/// # use serde_core::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
@@ -730,7 +745,7 @@ pub trait Serializer: Sized {
/// seq.end()
/// }
/// #
/// # serde::__serialize_unimplemented! {
/// # serde_core::__serialize_unimplemented! {
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant
/// # seq tuple tuple_struct tuple_variant map struct struct_variant
@@ -812,7 +827,7 @@ pub trait Serializer: Sized {
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// # serde_core::__private_serialize!();
/// #
/// impl Serialize for () {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -1494,6 +1509,12 @@ pub trait Serializer: Sized {
/// implementation of `SerializeSeq` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeSeq` is not satisfied",
)
)]
pub trait SerializeSeq {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1594,6 +1615,12 @@ pub trait SerializeSeq {
/// implementation of `SerializeTuple` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeTuple` is not satisfied",
)
)]
pub trait SerializeTuple {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1639,6 +1666,12 @@ pub trait SerializeTuple {
/// implementation of `SerializeTupleStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeTupleStruct` is not satisfied",
)
)]
pub trait SerializeTupleStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1697,6 +1730,12 @@ pub trait SerializeTupleStruct {
/// implementation of `SerializeTupleVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeTupleVariant` is not satisfied",
)
)]
pub trait SerializeTupleVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1763,6 +1802,12 @@ pub trait SerializeTupleVariant {
/// implementation of `SerializeMap` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeMap` is not satisfied",
)
)]
pub trait SerializeMap {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1853,6 +1898,12 @@ pub trait SerializeMap {
/// implementation of `SerializeStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeStruct` is not satisfied",
)
)]
pub trait SerializeStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1917,6 +1968,12 @@ pub trait SerializeStruct {
/// implementation of `SerializeStructVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
#[cfg_attr(
not(no_diagnostic_namespace),
diagnostic::on_unimplemented(
message = "the trait bound `{Self}: serde::ser::SerializeStructVariant` is not satisfied",
)
)]
pub trait SerializeStructVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -42,7 +42,7 @@ use crate::lib::{Debug, Display};
/// ```
pub trait Error: Debug + Display {
/// The underlying cause of this error, if any.
fn source(&self) -> Option<&(Error + 'static)> {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
+2 -2
View File
@@ -1,11 +1,11 @@
[package]
name = "serde_derive"
version = "1.0.219"
version = "1.0.221"
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)]"
documentation = "https://serde.rs/derive.html"
edition = "2015"
edition = "2021"
exclude = ["build.rs"]
homepage = "https://serde.rs"
keywords = ["serde", "serialization", "no_std", "derive"]
+1 -1
View File
@@ -2662,7 +2662,7 @@ fn deserialize_map(
if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
__collect.into_iter().filter(_serde::__private::Option::is_some).next()
{
if let _serde::__private::Some(__key) = __key.as_str() {
if let _serde::__private::Some(__key) = _serde::__private::de::content_as_str(&__key) {
return _serde::__private::Err(
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
} else {
+3
View File
@@ -22,6 +22,9 @@ pub fn wrap_in_const(serde_path: Option<&syn::Path>, code: TokenStream) -> Token
)]
const _: () = {
#use_serde
_serde::__require_serde_not_serde_core!();
#code
};
}
+2 -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.219")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.221")]
#![cfg_attr(not(check_cfg), allow(unexpected_cfgs))]
// Ignored clippy lints
#![allow(
@@ -64,6 +64,7 @@
clippy::wildcard_imports
)]
#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))]
#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
extern crate proc_macro2;
extern crate quote;
+1 -1
View File
@@ -150,7 +150,7 @@ fn build_generics(cont: &Container) -> syn::Generics {
}
// Fields with a `skip_serializing` or `serialize_with` attribute, or which
// belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
// belong to a variant with a `skip_serializing` or `serialize_with` attribute,
// are not serialized by us so we do not generate a bound. Fields with a `bound`
// attribute specify their own bound so we do not generate one. All other fields
// may need a `T: Serialize` bound where T is the type of the field.
+1 -1
View File
@@ -4,7 +4,7 @@ version = "0.29.1"
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"
edition = "2015"
edition = "2021"
exclude = ["build.rs"]
homepage = "https://serde.rs"
keywords = ["serde", "serialization"]
+1
View File
@@ -41,6 +41,7 @@
clippy::unused_self,
clippy::wildcard_imports
)]
#![allow(unknown_lints, mismatched_lifetime_syntaxes)]
extern crate proc_macro2;
extern crate quote;
+3 -3
View File
@@ -2,7 +2,7 @@
name = "serde_test_suite"
version = "0.0.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
edition = "2021"
publish = false
[features]
@@ -13,9 +13,9 @@ serde = { path = "../serde" }
[dev-dependencies]
automod = "1.0.1"
foldhash = "0.1"
foldhash = "0.2"
rustversion = "1.0"
serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = "1.0.176"
trybuild = { version = "1.0.97", features = ["diff"] }
trybuild = { version = "1.0.108", features = ["diff"] }
+1 -1
View File
@@ -2,7 +2,7 @@
name = "serde_derive_tests_no_std"
version = "0.0.0"
authors = ["David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
edition = "2021"
publish = false
[dependencies]
+2
View File
@@ -1,3 +1,5 @@
#![allow(dead_code)]
use serde_derive::Deserialize;
#[derive(Deserialize)]
+2
View File
@@ -1,3 +1,5 @@
#![allow(dead_code)]
use serde_derive::Deserialize;
macro_rules! bug {
+1
View File
@@ -2,4 +2,5 @@ use serde_derive::Serialize;
#[derive(Serialize)]
#[serde()]
#[allow(dead_code)]
pub struct S;
+1 -1
View File
@@ -1,4 +1,4 @@
#![allow(clippy::trivially_copy_pass_by_ref)]
#![allow(clippy::trivially_copy_pass_by_ref, dead_code)]
use serde_derive::{Deserialize, Serialize};
+1 -1
View File
@@ -1,4 +1,4 @@
#![allow(clippy::trivially_copy_pass_by_ref)]
#![allow(clippy::trivially_copy_pass_by_ref, dead_code)]
use serde_derive::Deserialize;
+4 -1
View File
@@ -1,7 +1,10 @@
#![allow(
clippy::derive_partial_eq_without_eq,
clippy::items_after_statements,
clippy::used_underscore_binding
clippy::used_underscore_binding,
// We use lots of declarations inside function bodies to avoid conflicts,
// but they aren't used. We just want to make sure they compile.
dead_code,
)]
use serde::de::value::{BorrowedStrDeserializer, MapDeserializer};
+9 -1
View File
@@ -18,7 +18,10 @@
clippy::ptr_arg,
clippy::too_many_lines,
clippy::trivially_copy_pass_by_ref,
clippy::type_repetition_in_bounds
clippy::type_repetition_in_bounds,
// We use lots of declarations inside function bodies to avoid conflicts,
// but they aren't used. We just want to make sure they compile.
dead_code,
)]
#![deny(clippy::collection_is_never_read)]
@@ -689,6 +692,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
#[allow(dead_code)]
pub enum UntaggedNewtypeVariantWith {
Newtype(
#[serde(serialize_with = "ser_x")]
@@ -699,6 +703,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(transparent)]
#[allow(dead_code)]
pub struct TransparentWith {
#[serde(serialize_with = "ser_x")]
#[serde(deserialize_with = "de_x")]
@@ -707,6 +712,7 @@ fn test_gen() {
#[derive(Deserialize)]
#[serde(untagged)]
#[allow(dead_code)]
pub enum UntaggedWithBorrow<'a> {
Single(
#[serde(borrow)]
@@ -805,6 +811,8 @@ fn test_gen() {
pub vec: Vec<Self>,
}
assert_ser::<Struct>();
#[derive(Deserialize)]
#[serde(bound(deserialize = "[&'de str; N]: Copy"))]
pub struct GenericUnitStruct<const N: usize>;
+1 -1
View File
@@ -1,4 +1,4 @@
#![allow(clippy::redundant_field_names)]
#![allow(clippy::redundant_field_names, dead_code)]
use serde_derive::{Deserialize, Serialize};
+1 -1
View File
@@ -1,4 +1,4 @@
#![allow(clippy::used_underscore_binding)]
#![allow(clippy::used_underscore_binding, dead_code)]
use serde_derive::{Deserialize, Serialize};
@@ -7,18 +7,18 @@ error[E0425]: cannot find value `__FAIL__` in this scope
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:13:9
|
8 | #[serde(alias = "a", alias = "b", alias = "c")]
8 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
13 | b: (),
| ^ no value can reach this
|
= note: `#[warn(unreachable_patterns)]` on by default
= note: `#[warn(unreachable_patterns)]` (part of `#[warn(unused)]`) on by default
warning: unreachable pattern
--> tests/ui/conflict/alias-enum.rs:12:25
|
8 | #[serde(alias = "a", alias = "b", alias = "c")]
8 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
12 | #[serde(alias = "c")]
+2 -2
View File
@@ -7,13 +7,13 @@ error[E0425]: cannot find value `__FAIL__` in this scope
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:10:5
|
5 | #[serde(alias = "a", alias = "b", alias = "c")]
5 | #[serde(alias = "a", alias = "b", alias = "c")]
| --- matches all the relevant values
...
10 | b: (),
| ^ no value can reach this
|
= note: `#[warn(unreachable_patterns)]` on by default
= note: `#[warn(unreachable_patterns)]` (part of `#[warn(unused)]`) on by default
warning: unreachable pattern
--> tests/ui/conflict/alias.rs:9:21
@@ -1,11 +1,11 @@
error: variant field name `conflict` conflicts with internal tag
--> tests/ui/conflict/internal-tag-alias.rs:4:1
|
4 | / #[serde(tag = "conflict")]
5 | | enum E {
6 | | A {
7 | | #[serde(alias = "conflict")]
8 | | x: (),
9 | | },
4 | / #[serde(tag = "conflict")]
5 | | enum E {
6 | | A {
7 | | #[serde(alias = "conflict")]
8 | | x: (),
9 | | },
10 | | }
| |_^
@@ -1,11 +1,11 @@
error: variant field name `conflict` conflicts with internal tag
--> tests/ui/conflict/internal-tag.rs:4:1
|
4 | / #[serde(tag = "conflict")]
5 | | enum E {
6 | | A {
7 | | #[serde(rename = "conflict")]
8 | | x: (),
9 | | },
4 | / #[serde(tag = "conflict")]
5 | | enum E {
6 | | A {
7 | | #[serde(rename = "conflict")]
8 | | x: (),
9 | | },
10 | | }
| |_^
@@ -1,7 +1,7 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:10:33
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -13,7 +13,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:12:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
@@ -25,7 +25,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_adjacently_tagged.rs:15:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -13,7 +13,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_externally_tagged.rs:11:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
@@ -25,7 +25,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_externally_tagged.rs:14:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -1,7 +1,7 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_internally_tagged.rs:12:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
@@ -13,7 +13,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_internally_tagged.rs:15:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -1,7 +1,7 @@
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:10:33
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -13,7 +13,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:12:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `u8`
@@ -25,7 +25,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_enum_untagged.rs:15:27
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -2,10 +2,7 @@ error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Newtype`, found `()`
| expected due to this
| ^^^^^^ expected `Newtype`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_newtype.rs:7:34
@@ -2,10 +2,7 @@ error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Struct`, found `()`
| expected due to this
| ^^^^^^ expected `Struct`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_struct.rs:8:23
@@ -22,7 +19,7 @@ error[E0308]: `match` arms have incompatible types
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_struct.rs:11:23
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| -----------
| |
| this is found to be of type `i8`
@@ -51,7 +48,7 @@ error[E0308]: mismatched types
error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_struct.rs:11:23
|
5 | #[derive(Deserialize)]
5 | #[derive(Deserialize)]
| ----------- expected due to the type of this binding
...
11 | #[serde(default = "main")]
@@ -2,10 +2,7 @@ error[E0308]: mismatched types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:6:19
|
6 | #[serde(default = "main")]
| ^^^^^^
| |
| expected `Tuple`, found `()`
| expected due to this
| ^^^^^^ expected `Tuple`, found `()`
error[E0308]: `match` arms have incompatible types
--> tests/ui/default-attribute/incorrect_type_tuple.rs:7:36
@@ -1,11 +1,11 @@
error: #[serde(transparent)] requires at least one field that is neither skipped nor has a default
--> tests/ui/transparent/de_at_least_one.rs:4:1
|
4 | / #[serde(transparent)]
5 | | struct S {
6 | | #[serde(skip)]
7 | | a: u8,
8 | | #[serde(default)]
9 | | b: u8,
4 | / #[serde(transparent)]
5 | | struct S {
6 | | #[serde(skip)]
7 | | a: u8,
8 | | #[serde(default)]
9 | | b: u8,
10 | | }
| |_^
@@ -0,0 +1,6 @@
struct MyStruct;
fn main() {
serde_test::assert_ser_tokens(&MyStruct, &[]);
serde_test::assert_de_tokens(&MyStruct, &[]);
}
@@ -0,0 +1,113 @@
error[E0277]: the trait bound `MyStruct: serde::Serialize` is not satisfied
--> tests/ui/unimplemented/required_by_dependency.rs:4:35
|
4 | serde_test::assert_ser_tokens(&MyStruct, &[]);
| ----------------------------- ^^^^^^^^^ unsatisfied trait bound
| |
| required by a bound introduced by this call
|
help: the trait `serde_core::ser::Serialize` is not implemented for `MyStruct`
--> tests/ui/unimplemented/required_by_dependency.rs:1:1
|
1 | struct MyStruct;
| ^^^^^^^^^^^^^^^
= note: for local types consider adding `#[derive(serde::Serialize)]` to your `MyStruct` type
= note: for types from other crates check whether the crate offers a `serde` feature flag
= help: the following other types implement trait `serde_core::ser::Serialize`:
&'a T
&'a mut T
()
(T,)
(T0, T1)
(T0, T1, T2)
(T0, T1, T2, T3)
(T0, T1, T2, T3, T4)
and $N others
note: required by a bound in `assert_ser_tokens`
--> $CARGO/serde_test-$VERSION/src/assert.rs
|
| pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
| ----------------- required by a bound in this function
| where
| T: ?Sized + Serialize,
| ^^^^^^^^^ required by this bound in `assert_ser_tokens`
error[E0277]: the trait bound `MyStruct: serde::Deserialize<'de>` is not satisfied
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
|
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
| ---------------------------- ^^^^^^^^^ unsatisfied trait bound
| |
| required by a bound introduced by this call
|
help: the trait `serde_core::de::Deserialize<'_>` is not implemented for `MyStruct`
--> tests/ui/unimplemented/required_by_dependency.rs:1:1
|
1 | struct MyStruct;
| ^^^^^^^^^^^^^^^
= note: for local types consider adding `#[derive(serde::Deserialize)]` to your `MyStruct` type
= note: for types from other crates check whether the crate offers a `serde` feature flag
= help: the following other types implement trait `serde_core::de::Deserialize<'de>`:
&'a Path
&'a [u8]
&'a str
()
(T,)
(T0, T1)
(T0, T1, T2)
(T0, T1, T2, T3)
and $N others
note: required by a bound in `assert_de_tokens`
--> $CARGO/serde_test-$VERSION/src/assert.rs
|
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
| ---------------- required by a bound in this function
| where
| T: Deserialize<'de> + PartialEq + Debug,
| ^^^^^^^^^^^^^^^^ required by this bound in `assert_de_tokens`
error[E0277]: can't compare `MyStruct` with `MyStruct`
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
|
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
| ---------------------------- ^^^^^^^^^ no implementation for `MyStruct == MyStruct`
| |
| required by a bound introduced by this call
|
= help: the trait `PartialEq` is not implemented for `MyStruct`
note: required by a bound in `assert_de_tokens`
--> $CARGO/serde_test-$VERSION/src/assert.rs
|
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
| ---------------- required by a bound in this function
| where
| T: Deserialize<'de> + PartialEq + Debug,
| ^^^^^^^^^ required by this bound in `assert_de_tokens`
help: consider annotating `MyStruct` with `#[derive(PartialEq)]`
|
1 + #[derive(PartialEq)]
2 | struct MyStruct;
|
error[E0277]: `MyStruct` doesn't implement `Debug`
--> tests/ui/unimplemented/required_by_dependency.rs:5:34
|
5 | serde_test::assert_de_tokens(&MyStruct, &[]);
| ---------------------------- ^^^^^^^^^ the trait `Debug` is not implemented for `MyStruct`
| |
| required by a bound introduced by this call
|
= note: add `#[derive(Debug)]` to `MyStruct` or manually `impl Debug for MyStruct`
note: required by a bound in `assert_de_tokens`
--> $CARGO/serde_test-$VERSION/src/assert.rs
|
| pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
| ---------------- required by a bound in this function
| where
| T: Deserialize<'de> + PartialEq + Debug,
| ^^^^^ required by this bound in `assert_de_tokens`
help: consider annotating `MyStruct` with `#[derive(Debug)]`
|
1 + #[derive(Debug)]
2 | struct MyStruct;
|
@@ -1,11 +1,16 @@
error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied
--> tests/ui/on_unimplemented.rs:21:15
error[E0277]: the trait bound `MyStruct: serde::Serialize` is not satisfied
--> tests/ui/unimplemented/required_locally.rs:21:15
|
21 | to_string(&MyStruct);
| --------- ^^^^^^^^^ the trait `Serialize` is not implemented for `MyStruct`
| --------- ^^^^^^^^^ unsatisfied trait bound
| |
| required by a bound introduced by this call
|
help: the trait `Serialize` is not implemented for `MyStruct`
--> tests/ui/unimplemented/required_locally.rs:18:1
|
18 | struct MyStruct;
| ^^^^^^^^^^^^^^^
= note: for local types consider adding `#[derive(serde::Serialize)]` to your `MyStruct` type
= note: for types from other crates check whether the crate offers a `serde` feature flag
= help: the following other types implement trait `Serialize`:
@@ -19,20 +24,25 @@ error[E0277]: the trait bound `MyStruct: Serialize` is not satisfied
(T0, T1, T2, T3, T4)
and $N others
note: required by a bound in `to_string`
--> tests/ui/on_unimplemented.rs:6:8
--> tests/ui/unimplemented/required_locally.rs:6:8
|
4 | fn to_string<T>(_: &T) -> String
4 | fn to_string<T>(_: &T) -> String
| --------- required by a bound in this function
5 | where
6 | T: Serialize,
5 | where
6 | T: Serialize,
| ^^^^^^^^^ required by this bound in `to_string`
error[E0277]: the trait bound `MyStruct: Deserialize<'_>` is not satisfied
--> tests/ui/on_unimplemented.rs:22:23
error[E0277]: the trait bound `MyStruct: serde::Deserialize<'de>` is not satisfied
--> tests/ui/unimplemented/required_locally.rs:22:23
|
22 | let _: MyStruct = from_str("");
| ^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `MyStruct`
| ^^^^^^^^^^^^ unsatisfied trait bound
|
help: the trait `Deserialize<'_>` is not implemented for `MyStruct`
--> tests/ui/unimplemented/required_locally.rs:18:1
|
18 | struct MyStruct;
| ^^^^^^^^^^^^^^^
= note: for local types consider adding `#[derive(serde::Deserialize)]` to your `MyStruct` type
= note: for types from other crates check whether the crate offers a `serde` feature flag
= help: the following other types implement trait `Deserialize<'de>`:
@@ -46,7 +56,7 @@ error[E0277]: the trait bound `MyStruct: Deserialize<'_>` is not satisfied
(T0, T1, T2, T3)
and $N others
note: required by a bound in `from_str`
--> tests/ui/on_unimplemented.rs:13:8
--> tests/ui/unimplemented/required_locally.rs:13:8
|
11 | fn from_str<'de, T>(_: &'de str) -> T
| -------- required by a bound in this function
@@ -1,10 +1,10 @@
error: variant `Struct` cannot have both #[serde(deserialize_with)] and a field `f1` marked with #[serde(skip_deserializing)]
--> tests/ui/with-variant/skip_de_struct_field.rs:5:5
|
5 | / #[serde(deserialize_with = "deserialize_some_other_variant")]
6 | | Struct {
7 | | #[serde(skip_deserializing)]
8 | | f1: String,
9 | | f2: u8,
5 | / #[serde(deserialize_with = "deserialize_some_other_variant")]
6 | | Struct {
7 | | #[serde(skip_deserializing)]
8 | | f1: String,
9 | | f2: u8,
10 | | },
| |_____^
@@ -1,10 +1,10 @@
error: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing)]
--> tests/ui/with-variant/skip_ser_struct_field.rs:5:5
|
5 | / #[serde(serialize_with = "serialize_some_other_variant")]
6 | | Struct {
7 | | #[serde(skip_serializing)]
8 | | f1: String,
9 | | f2: u8,
5 | / #[serde(serialize_with = "serialize_some_other_variant")]
6 | | Struct {
7 | | #[serde(skip_serializing)]
8 | | f1: String,
9 | | f2: u8,
10 | | },
| |_____^
@@ -1,10 +1,10 @@
error: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing_if)]
--> tests/ui/with-variant/skip_ser_struct_field_if.rs:5:5
|
5 | / #[serde(serialize_with = "serialize_some_newtype_variant")]
6 | | Struct {
7 | | #[serde(skip_serializing_if = "always")]
8 | | f1: String,
9 | | f2: u8,
5 | / #[serde(serialize_with = "serialize_some_newtype_variant")]
6 | | Struct {
7 | | #[serde(skip_serializing_if = "always")]
8 | | f1: String,
9 | | f2: u8,
10 | | },
| |_____^
@@ -1,4 +1,4 @@
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:14:10
|
14 | #[derive(Serialize, Deserialize)]
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `&u8: Serializer` is not satisfied
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^^ required by this bound in `serialize`
error[E0061]: this function takes 1 argument but 2 arguments were supplied
@@ -27,10 +27,10 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:15:25
|
15 | struct W(#[serde(with = "w")] u8, u8);
@@ -49,7 +49,7 @@ error[E0308]: `?` operator has incompatible types
|
= note: `?` operator cannot convert from `()` to `u8`
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:17:10
|
17 | #[derive(Serialize, Deserialize)]
@@ -64,7 +64,7 @@ error[E0277]: the trait bound `&u8: Serializer` is not satisfied
note: required by a bound in `w::serialize`
--> tests/ui/with/incorrect_type.rs:9:28
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^^ required by this bound in `serialize`
error[E0061]: this function takes 1 argument but 2 arguments were supplied
@@ -78,10 +78,10 @@ error[E0061]: this function takes 1 argument but 2 arguments were supplied
note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12
|
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
9 | pub fn serialize<T, S: Serializer>(_: S) -> Result<S::Ok, S::Error> {
| ^^^^^^^^^
error[E0277]: the trait bound `&u8: Serializer` is not satisfied
error[E0277]: the trait bound `&u8: serde::Serializer` is not satisfied
--> tests/ui/with/incorrect_type.rs:18:35
|
18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);