Compare commits

...

31 Commits

Author SHA1 Message Date
David Tolnay edb1a586d8 Release 1.0.190 2023-10-25 20:05:13 -07:00
David Tolnay 11c2917040 Merge pull request #2637 from dtolnay/nansign
Ensure f32 deserialized from f64 and vice versa preserve NaN sign
2023-10-25 20:03:05 -07:00
David Tolnay 6ba9c12ff6 Float copysign does not exist in libcore yet 2023-10-25 19:55:14 -07:00
David Tolnay d2fcc346b9 Ensure f32 deserialized from f64 and vice versa preserve NaN sign 2023-10-25 19:45:53 -07:00
David Tolnay a091a07aa2 Add float NaN tests 2023-10-25 19:45:53 -07:00
David Tolnay bb4135cae8 Fix unused imports
warning: unused imports: `cmp`, `mem`, `slice`
       --> serde/src/lib.rs:171:26
        |
    171 |     pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
        |                          ^^^        ^^^            ^^^^^
        |
        = note: `#[warn(unused_imports)]` on by default
2023-10-24 22:32:42 -07:00
David Tolnay 8de84b7ca3 Resolve get_first clippy lint
warning: accessing first element with `variant.fields.get(0)`
        --> serde_derive/src/de.rs:1843:27
         |
    1843 |             let default = variant.fields.get(0).map(|field| {
         |                           ^^^^^^^^^^^^^^^^^^^^^ help: try: `variant.fields.first()`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first
         = note: `-W clippy::get-first` implied by `-W clippy::all`
         = help: to override `-W clippy::all` add `#[allow(clippy::get_first)]`

    warning: accessing first element with `variant.fields.get(0)`
        --> serde_derive/src/de.rs:1888:27
         |
    1888 |             let default = variant.fields.get(0).map(|field| {
         |                           ^^^^^^^^^^^^^^^^^^^^^ help: try: `variant.fields.first()`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first
2023-10-21 22:01:10 -07:00
David Tolnay 9cdf332029 Remove 'remember to update' reminder from Cargo.toml 2023-10-17 21:05:31 -07:00
David Tolnay e94fc65f01 Release 1.0.189 2023-10-12 19:20:43 -07:00
David Tolnay b908487476 Remove double nesting of first_attempt
`expr` is of type serde_derive::fragment::Expr, which can be
interpolated directly in any expression position. It does not
need to be nested in another set of braces.
2023-10-12 19:18:42 -07:00
David Tolnay 2a7c7faeb4 Merge pull request #2613 from ahl/fix-untagged-plus-simple
"cannot infer type" from Deserialize derive macro with simple variants and untagged variants
2023-10-12 19:15:32 -07:00
David Tolnay e302e15eea Merge pull request #2625 from marcospb19/add-csv-to-the-list
Add CSV to the formats list
2023-10-09 19:23:12 -07:00
João Marcos P. Bezerra 1cbea892cf Add CSV to the formats list 2023-10-09 22:59:56 -03:00
David Tolnay 37a32857a2 Update ui test suite to nightly-2023-10-06 2023-10-05 23:24:34 -04:00
David Tolnay 8c4aad3a59 Clean up unneeded raw strings in test 2023-09-26 19:09:30 -07:00
David Tolnay 1774794b19 Resolve needless_raw_string_hashes clippy lint in test
warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2722:9
         |
    2722 |         r#"invalid type: unit value, expected variant identifier"#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
         = note: `-W clippy::needless-raw-string-hashes` implied by `-W clippy::all`
         = help: to override `-W clippy::all` add `#[allow(clippy::needless_raw_string_hashes)]`
    help: remove all the hashes around the literal
         |
    2722 -         r#"invalid type: unit value, expected variant identifier"#,
    2722 +         r"invalid type: unit value, expected variant identifier",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2743:9
         |
    2743 |         r#"invalid type: unit value, expected variant identifier"#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2743 -         r#"invalid type: unit value, expected variant identifier"#,
    2743 +         r"invalid type: unit value, expected variant identifier",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2769:9
         |
    2769 |         r#"invalid type: unit value, expected variant of enum Enum"#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2769 -         r#"invalid type: unit value, expected variant of enum Enum"#,
    2769 +         r"invalid type: unit value, expected variant of enum Enum",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2782:63
         |
    2782 |     assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r#"something strange..."#);
         |                                                               ^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2782 -     assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r#"something strange..."#);
    2782 +     assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r"something strange...");
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2803:9
         |
    2803 |         r#"invalid type: unit value, expected something strange..."#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2803 -         r#"invalid type: unit value, expected something strange..."#,
    2803 +         r"invalid type: unit value, expected something strange...",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2812:9
         |
    2812 |         r#"invalid type: map, expected something strange..."#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2812 -         r#"invalid type: map, expected something strange..."#,
    2812 +         r"invalid type: map, expected something strange...",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2817:9
         |
    2817 |         r#"invalid type: unit value, expected something strange..."#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2817 -         r#"invalid type: unit value, expected something strange..."#,
    2817 +         r"invalid type: unit value, expected something strange...",
         |

    warning: unnecessary hashes around raw string literal
        --> test_suite/tests/test_annotations.rs:2828:9
         |
    2828 |         r#"invalid type: map, expected something strange..."#,
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_raw_string_hashes
    help: remove all the hashes around the literal
         |
    2828 -         r#"invalid type: map, expected something strange..."#,
    2828 +         r"invalid type: map, expected something strange...",
         |
2023-09-26 19:05:18 -07:00
David Tolnay 1af23f1f2d Test docs.rs documentation build in CI 2023-09-24 10:53:44 -07:00
Adam H. Leventhal 94fbc3d388 fix clippy 2023-09-07 22:17:22 -07:00
Adam H. Leventhal 8da2058e2a fix deserialization of untagged variants within internally or adjacently
tagged enums
2023-09-07 17:19:27 -07:00
Adam H. Leventhal 09993a904a Fix for "cannot infer type" from Deserialize derive macro with simple
variants and untagged variants
2023-09-06 15:33:28 -07:00
Adam H. Leventhal 5d1403461c add failing test 2023-09-06 15:31:16 -07:00
David Tolnay ddc1ee564b Release serde_derive_internals 0.29.0 2023-09-06 14:02:05 -07:00
David Tolnay 00a54b848a Update actions/checkout@v3 -> v4 2023-09-04 22:35:02 -07:00
David Tolnay dad15b9fd0 Release 1.0.188 2023-08-25 19:16:10 -07:00
David Tolnay d89c19f903 Revert "Adopt new Cargo feature resolver"
This reverts commit e1c27243b2.

Closes https://github.com/serde-rs/serde/issues/2603.
2023-08-25 19:15:26 -07:00
David Tolnay 146dc0fad5 Release 1.0.187 2023-08-25 10:53:36 -07:00
David Tolnay d26852deef Merge pull request #2602 from dtolnay/resolver
Adopt new Cargo feature resolver
2023-08-25 10:52:42 -07:00
David Tolnay e1c27243b2 Adopt new Cargo feature resolver 2023-08-25 10:35:02 -07:00
David Tolnay dbbfe7abe2 Merge pull request #2600 from dtolnay/oldemscripten
Remove support for emscripten targets on rustc older than 1.40
2023-08-23 22:18:20 -07:00
David Tolnay dc24d12ce0 Clean up all usage of serde_if_integer128 2023-08-23 22:14:23 -07:00
David Tolnay 4e7533e872 Remove support for emscripten targets on rustc older than 1.40 2023-08-23 22:07:21 -07:00
21 changed files with 332 additions and 313 deletions
+25 -11
View File
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: cd test_suite && cargo test --features unstable
@@ -27,7 +27,7 @@ jobs:
runs-on: windows-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: cd test_suite && cargo test --features unstable -- --skip ui --exact
@@ -40,7 +40,7 @@ jobs:
rust: [stable, beta]
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -56,7 +56,7 @@ jobs:
os: [ubuntu, windows]
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: cd serde && cargo build
- run: cd serde && cargo build --no-default-features
@@ -80,7 +80,7 @@ jobs:
rust: [1.31.0, 1.34.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -93,7 +93,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.56.0
- run: cd serde && cargo check --no-default-features
- run: cd serde && cargo check
@@ -104,7 +104,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.36.0
- run: cd serde && cargo build --no-default-features --features alloc
@@ -113,18 +113,32 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- run: cargo generate-lockfile -Z minimal-versions
- run: cargo check --locked --workspace
doc:
name: Documentation
runs-on: ubuntu-latest
timeout-minutes: 45
env:
RUSTDOCFLAGS: -Dwarnings
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/install@cargo-docs-rs
- run: cargo docs-rs -p serde
- run: cargo docs-rs -p serde_derive
- run: cargo docs-rs -p serde_derive_internals
clippy:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@clippy
- run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
@@ -137,7 +151,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@miri
- run: cargo miri setup
- run: cd serde && cargo miri test --features derive,rc,unstable
@@ -153,6 +167,6 @@ jobs:
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: dtolnay/install@cargo-outdated
- run: cargo outdated --workspace --exit-code 1
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.186" # remember to update html_root_url and serde_derive dependency
version = "1.0.190"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
@@ -37,7 +37,7 @@ rustdoc-args = ["--generate-link-to-definition"]
# 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.186", path = "../serde_derive" }
serde_derive = { version = "=1.0.190", path = "../serde_derive" }
### FEATURES #################################################################
+4 -5
View File
@@ -27,11 +27,10 @@ fn main() {
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
}
// Disabled on Emscripten targets before Rust 1.40 since
// Emscripten did not support 128-bit integers until Rust 1.40
// (https://github.com/rust-lang/rust/pull/65251)
if emscripten && minor < 40 {
println!("cargo:rustc-cfg=no_integer128");
// 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");
}
// Current minimum supported version of serde_derive crate is Rust 1.56.
+8 -12
View File
@@ -129,12 +129,10 @@ impl<'de> Visitor<'de> for IgnoredAny {
Ok(IgnoredAny)
}
serde_if_integer128! {
#[inline]
fn visit_i128<E>(self, x: i128) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_i128<E>(self, x: i128) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
@@ -143,12 +141,10 @@ impl<'de> Visitor<'de> for IgnoredAny {
Ok(IgnoredAny)
}
serde_if_integer128! {
#[inline]
fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
+71 -51
View File
@@ -180,6 +180,28 @@ macro_rules! num_as_self {
};
}
macro_rules! num_as_copysign_self {
($ty:ident : $visit:ident) => {
#[inline]
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
{
#[cfg(any(no_float_copysign, not(feature = "std")))]
{
Ok(v as Self::Value)
}
#[cfg(all(not(no_float_copysign), feature = "std"))]
{
// Preserve sign of NaN. The `as` produces a nondeterministic sign.
let sign = if v.is_sign_positive() { 1.0 } else { -1.0 };
Ok((v as Self::Value).copysign(sign))
}
}
};
}
macro_rules! int_to_int {
($ty:ident : $visit:ident) => {
#[inline]
@@ -351,7 +373,7 @@ impl_deserialize_num! {
impl_deserialize_num! {
f32, deserialize_f32
num_self!(f32:visit_f32);
num_as_self!(f64:visit_f64);
num_as_copysign_self!(f64:visit_f64);
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);
}
@@ -359,69 +381,67 @@ impl_deserialize_num! {
impl_deserialize_num! {
f64, deserialize_f64
num_self!(f64:visit_f64);
num_as_self!(f32:visit_f32);
num_as_copysign_self!(f32:visit_f32);
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);
}
serde_if_integer128! {
macro_rules! num_128 {
($ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
macro_rules! num_128 {
($ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
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_value() as i128
&& v as u128 <= Self::Value::max_value() as u128
{
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(
Unexpected::Other(stringify!($ty)),
&self,
))
}
Ok(v as Self::Value)
} else {
Err(Error::invalid_value(
Unexpected::Other(stringify!($ty)),
&self,
))
}
};
}
};
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: Error,
(nonzero $primitive:ident $ty:ident : $visit:ident) => {
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
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_value() as i128
&& v as u128 <= $primitive::max_value() as u128
{
if let Some(nonzero) = Self::Value::new(v as $primitive) {
Ok(nonzero)
} else {
Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
}
if let Some(nonzero) = Self::Value::new(v as $primitive) {
Ok(nonzero)
} else {
Err(Error::invalid_value(
Unexpected::Other(stringify!($ty)),
&self,
))
Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
}
} else {
Err(Error::invalid_value(
Unexpected::Other(stringify!($ty)),
&self,
))
}
};
}
}
};
}
impl_deserialize_num! {
i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), 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);
num_128!(u128:visit_u128);
}
impl_deserialize_num! {
i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), 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);
num_128!(u128:visit_u128);
}
impl_deserialize_num! {
u128, NonZeroU128, deserialize_u128
num_self!(u128:visit_u128);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
num_128!(i128:visit_i128);
}
impl_deserialize_num! {
u128, NonZeroU128, deserialize_u128
num_self!(u128:visit_u128);
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
num_128!(i128:visit_i128);
}
////////////////////////////////////////////////////////////////////////////////
+46 -53
View File
@@ -118,7 +118,6 @@ use crate::lib::*;
pub mod value;
#[cfg(not(no_integer128))]
mod format;
mod ignored_any;
mod impls;
@@ -949,18 +948,15 @@ pub trait Deserializer<'de>: Sized {
where
V: Visitor<'de>;
serde_if_integer128! {
/// Hint that the `Deserialize` type is expecting an `i128` value.
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default behavior unconditionally returns an error.
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
let _ = visitor;
Err(Error::custom("i128 is not supported"))
}
/// Hint that the `Deserialize` type is expecting an `i128` value.
///
/// The default behavior unconditionally returns an error.
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let _ = visitor;
Err(Error::custom("i128 is not supported"))
}
/// Hint that the `Deserialize` type is expecting a `u8` value.
@@ -983,18 +979,15 @@ pub trait Deserializer<'de>: Sized {
where
V: Visitor<'de>;
serde_if_integer128! {
/// Hint that the `Deserialize` type is expecting an `u128` value.
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default behavior unconditionally returns an error.
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>
{
let _ = visitor;
Err(Error::custom("u128 is not supported"))
}
/// Hint that the `Deserialize` type is expecting an `u128` value.
///
/// The default behavior unconditionally returns an error.
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let _ = visitor;
Err(Error::custom("u128 is not supported"))
}
/// Hint that the `Deserialize` type is expecting a `f32` value.
@@ -1366,20 +1359,20 @@ pub trait Visitor<'de>: Sized {
Err(Error::invalid_type(Unexpected::Signed(v), &self))
}
serde_if_integer128! {
/// The input contains a `i128`.
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default implementation fails with a type error.
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: Error,
{
let mut buf = [0u8; 58];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
/// The input contains a `i128`.
///
/// The default implementation fails with a type error.
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: Error,
{
let mut buf = [0u8; 58];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
&self,
))
}
/// The input contains a `u8`.
@@ -1428,20 +1421,20 @@ pub trait Visitor<'de>: Sized {
Err(Error::invalid_type(Unexpected::Unsigned(v), &self))
}
serde_if_integer128! {
/// The input contains a `u128`.
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default implementation fails with a type error.
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: Error,
{
let mut buf = [0u8; 57];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
/// The input contains a `u128`.
///
/// The default implementation fails with a type error.
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: Error,
{
let mut buf = [0u8; 57];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(
Unexpected::Other(writer.as_str()),
&self,
))
}
/// The input contains an `f32`.
+2 -5
View File
@@ -292,20 +292,17 @@ primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8);
primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16);
primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32);
primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64);
primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128);
primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64);
primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8);
primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16);
primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64);
primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128);
primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64);
primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32);
primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64);
primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char);
serde_if_integer128! {
primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128);
primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128);
}
/// A deserializer holding a `u32`.
pub struct U32Deserializer<E> {
value: u32,
+3 -76
View File
@@ -1,82 +1,9 @@
/// Conditional compilation depending on whether Serde is built with support for
/// 128-bit integers.
///
/// Data formats that wish to support Rust compiler versions older than 1.26
/// (or targets that lack 128-bit integers) may place the i128 / u128 methods
/// of their Serializer and Deserializer behind this macro.
///
/// Data formats that require a minimum Rust compiler version of at least 1.26,
/// or do not target platforms that lack 128-bit integers, do not need to
/// bother with this macro and may assume support for 128-bit integers.
///
/// ```edition2021
/// # use serde::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
/// use serde::{serde_if_integer128, Serializer};
///
/// impl Serializer for MySerializer {
/// type Ok = ();
/// type Error = Error;
///
/// fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
/// /* ... */
/// # unimplemented!()
/// }
///
/// /* ... */
///
/// serde_if_integer128! {
/// fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
/// /* ... */
/// # unimplemented!()
/// }
///
/// fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
/// /* ... */
/// # unimplemented!()
/// }
/// }
/// #
/// # serde::__serialize_unimplemented! {
/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant seq
/// # tuple tuple_struct tuple_variant map struct struct_variant
/// # }
/// }
/// ```
///
/// When Serde is built with support for 128-bit integers, this macro expands
/// transparently into just the input tokens.
///
/// ```edition2021
/// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => {
/// $($tt)*
/// };
/// }
/// ```
///
/// When built without support for 128-bit integers, this macro expands to
/// nothing.
///
/// ```edition2021
/// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => {};
/// }
/// ```
#[cfg(not(no_integer128))]
// No longer used. Old versions of serde used this macro for supporting targets
// that did not yet have 128-bit integer support.
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
($($tt:tt)*) => {
$($tt)*
};
}
#[cfg(no_integer128)]
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
($($tt:tt)*) => {};
}
+7 -2
View File
@@ -63,6 +63,7 @@
//! and from DynamoDB.
//! - [Hjson], a syntax extension to JSON designed around human reading and
//! editing. *(deserialization only)*
//! - [CSV], Comma-separated values is a tabular text file format.
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Postcard]: https://github.com/jamesmunns/postcard
@@ -89,11 +90,12 @@
//! [DynamoDB Items]: https://docs.rs/serde_dynamo
//! [rusoto_dynamodb]: https://docs.rs/rusoto_dynamodb
//! [Hjson]: https://github.com/Canop/deser-hjson
//! [CSV]: https://docs.rs/csv
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.186")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.190")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
@@ -166,11 +168,14 @@ mod lib {
pub use std::*;
}
pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
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};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::core::{cmp, mem, slice};
pub use self::core::cell::{Cell, RefCell};
pub use self::core::clone::{self, Clone};
pub use self::core::cmp::Reverse;
+2 -6
View File
@@ -154,9 +154,7 @@ macro_rules! forward_to_deserialize_any_helper {
forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()}
};
(i128<$l:tt, $v:ident>) => {
serde_if_integer128! {
forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()}
}
forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()}
};
(u8<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()}
@@ -171,9 +169,7 @@ macro_rules! forward_to_deserialize_any_helper {
forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()}
};
(u128<$l:tt, $v:ident>) => {
serde_if_integer128! {
forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()}
}
forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()}
};
(f32<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()}
+2 -7
View File
@@ -52,10 +52,12 @@ impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
serialize_i16: i16,
serialize_i32: i32,
serialize_i64: i64,
serialize_i128: i128,
serialize_u8: u8,
serialize_u16: u16,
serialize_u32: u32,
serialize_u64: u64,
serialize_u128: u128,
serialize_f32: f32,
serialize_f64: f64,
serialize_char: char,
@@ -63,13 +65,6 @@ impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
serialize_unit_struct: &'static str,
}
serde_if_integer128! {
fmt_primitives! {
serialize_i128: i128,
serialize_u128: u128,
}
}
fn serialize_unit_variant(
self,
_name: &'static str,
+4 -18
View File
@@ -24,20 +24,17 @@ primitive_impl!(i8, serialize_i8);
primitive_impl!(i16, serialize_i16);
primitive_impl!(i32, serialize_i32);
primitive_impl!(i64, serialize_i64);
primitive_impl!(i128, serialize_i128);
primitive_impl!(usize, serialize_u64 as u64);
primitive_impl!(u8, serialize_u8);
primitive_impl!(u16, serialize_u16);
primitive_impl!(u32, serialize_u32);
primitive_impl!(u64, serialize_u64);
primitive_impl!(u128, serialize_u128);
primitive_impl!(f32, serialize_f32);
primitive_impl!(f64, serialize_f64);
primitive_impl!(char, serialize_char);
serde_if_integer128! {
primitive_impl!(i128, serialize_i128);
primitive_impl!(u128, serialize_u128);
}
////////////////////////////////////////////////////////////////////////////////
impl Serialize for str {
@@ -553,6 +550,7 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
NonZeroU128,
NonZeroUsize,
}
@@ -562,22 +560,10 @@ nonzero_integers! {
NonZeroI16,
NonZeroI32,
NonZeroI64,
NonZeroI128,
NonZeroIsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
#[cfg(not(no_num_nonzero_signed))]
nonzero_integers! {
NonZeroI128,
}
}
impl<T> Serialize for Cell<T>
where
T: Serialize + Copy,
+42 -48
View File
@@ -488,30 +488,27 @@ pub trait Serializer: Sized {
/// ```
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
serde_if_integer128! {
/// Serialize an `i128` value.
///
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// #
/// impl Serialize for i128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where
/// S: Serializer,
/// {
/// serializer.serialize_i128(*self)
/// }
/// }
/// ```
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default behavior unconditionally returns an error.
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
let _ = v;
Err(Error::custom("i128 is not supported"))
}
/// Serialize an `i128` value.
///
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// #
/// impl Serialize for i128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where
/// S: Serializer,
/// {
/// serializer.serialize_i128(*self)
/// }
/// }
/// ```
///
/// The default behavior unconditionally returns an error.
fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
let _ = v;
Err(Error::custom("i128 is not supported"))
}
/// Serialize a `u8` value.
@@ -598,30 +595,27 @@ pub trait Serializer: Sized {
/// ```
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
serde_if_integer128! {
/// Serialize a `u128` value.
///
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// #
/// impl Serialize for u128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where
/// S: Serializer,
/// {
/// serializer.serialize_u128(*self)
/// }
/// }
/// ```
///
/// This method is available only on Rust compiler versions >=1.26. The
/// default behavior unconditionally returns an error.
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
let _ = v;
Err(Error::custom("u128 is not supported"))
}
/// Serialize a `u128` value.
///
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
/// #
/// impl Serialize for u128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where
/// S: Serializer,
/// {
/// serializer.serialize_u128(*self)
/// }
/// }
/// ```
///
/// The default behavior unconditionally returns an error.
fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
let _ = v;
Err(Error::custom("u128 is not supported"))
}
/// Serialize an `f32` value.
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.186" # remember to update html_root_url
version = "1.0.190"
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)]"
+15 -3
View File
@@ -1737,7 +1737,6 @@ fn deserialize_untagged_enum_after(
quote!(__deserializer),
))
});
let attempts = first_attempt.into_iter().chain(attempts);
// TODO this message could be better by saving the errors from the failed
// attempts. The heuristic used by TOML was to count the number of fields
// processed before an error, and use the error that happened after the
@@ -1750,10 +1749,23 @@ fn deserialize_untagged_enum_after(
);
let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg);
// Ignore any error associated with non-untagged deserialization so that we
// can fall through to the untagged variants. This may be infallible so we
// need to provide the error type.
let first_attempt = first_attempt.map(|expr| {
quote! {
if let _serde::__private::Result::<_, __D::Error>::Ok(__ok) = (|| #expr)() {
return _serde::__private::Ok(__ok);
}
}
});
quote_block! {
let __content = <_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)?;
let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
#first_attempt
#(
if let _serde::__private::Ok(__ok) = #attempts {
return _serde::__private::Ok(__ok);
@@ -1828,7 +1840,7 @@ fn deserialize_internally_tagged_variant(
let this_value = &params.this_value;
let type_name = params.type_name();
let variant_name = variant.ident.to_string();
let default = variant.fields.get(0).map(|field| {
let default = variant.fields.first().map(|field| {
let default = Expr(expr_is_missing(field, cattrs));
quote!((#default))
});
@@ -1873,7 +1885,7 @@ fn deserialize_untagged_variant(
let this_value = &params.this_value;
let type_name = params.type_name();
let variant_name = variant.ident.to_string();
let default = variant.fields.get(0).map(|field| {
let default = variant.fields.first().map(|field| {
let default = Expr(expr_is_missing(field, cattrs));
quote!((#default))
});
+1 -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.186")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.190")]
// Ignored clippy lints
#![allow(
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive_internals"
version = "0.28.0" # remember to update html_root_url
version = "0.29.0"
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"
+1 -1
View File
@@ -1,4 +1,4 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.28.0")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.29.0")]
// Ignored clippy lints
#![allow(
clippy::cognitive_complexity,
+70 -8
View File
@@ -2380,6 +2380,68 @@ fn test_partially_untagged_enum_desugared() {
);
}
#[test]
fn test_partially_untagged_internally_tagged_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t")]
enum Data {
A,
B,
#[serde(untagged)]
Var(u32),
}
let data = Data::A;
assert_de_tokens(
&data,
&[
Token::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::MapEnd,
],
);
let data = Data::Var(42);
assert_de_tokens(&data, &[Token::U32(42)]);
// TODO test error output
}
#[test]
fn test_partially_untagged_adjacently_tagged_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[serde(tag = "t", content = "c")]
enum Data {
A(u32),
B,
#[serde(untagged)]
Var(u32),
}
let data = Data::A(7);
assert_de_tokens(
&data,
&[
Token::Map { len: None },
Token::Str("t"),
Token::Str("A"),
Token::Str("c"),
Token::U32(7),
Token::MapEnd,
],
);
let data = Data::Var(42);
assert_de_tokens(&data, &[Token::U32(42)]);
// TODO test error output
}
#[test]
fn test_flatten_option() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -2719,7 +2781,7 @@ fn test_expecting_message_externally_tagged_enum() {
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
assert_de_tokens_error::<Enum>(
&[Token::Enum { name: "Enum" }, Token::Unit],
r#"invalid type: unit value, expected variant identifier"#,
"invalid type: unit value, expected variant identifier",
);
}
@@ -2740,7 +2802,7 @@ fn test_expecting_message_internally_tagged_enum() {
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
assert_de_tokens_error::<Enum>(
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
r#"invalid type: unit value, expected variant identifier"#,
"invalid type: unit value, expected variant identifier",
);
}
@@ -2766,7 +2828,7 @@ fn test_expecting_message_adjacently_tagged_enum() {
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
assert_de_tokens_error::<Enum>(
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
r#"invalid type: unit value, expected variant of enum Enum"#,
"invalid type: unit value, expected variant of enum Enum",
);
}
@@ -2779,7 +2841,7 @@ fn test_expecting_message_untagged_tagged_enum() {
Untagged,
}
assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], r#"something strange..."#);
assert_de_tokens_error::<Enum>(&[Token::Str("Untagged")], "something strange...");
}
#[test]
@@ -2800,7 +2862,7 @@ fn test_expecting_message_identifier_enum() {
assert_de_tokens_error::<FieldEnum>(
&[Token::Unit],
r#"invalid type: unit value, expected something strange..."#,
"invalid type: unit value, expected something strange...",
);
assert_de_tokens_error::<FieldEnum>(
@@ -2809,12 +2871,12 @@ fn test_expecting_message_identifier_enum() {
Token::Str("Unknown"),
Token::None,
],
r#"invalid type: map, expected something strange..."#,
"invalid type: map, expected something strange...",
);
assert_de_tokens_error::<VariantEnum>(
&[Token::Unit],
r#"invalid type: unit value, expected something strange..."#,
"invalid type: unit value, expected something strange...",
);
assert_de_tokens_error::<VariantEnum>(
@@ -2825,7 +2887,7 @@ fn test_expecting_message_identifier_enum() {
Token::Str("Unknown"),
Token::None,
],
r#"invalid type: map, expected something strange..."#,
"invalid type: map, expected something strange...",
);
}
+21
View File
@@ -11,6 +11,7 @@
#![cfg_attr(feature = "unstable", feature(never_type))]
use fnv::FnvHasher;
use serde::de::value::{F32Deserializer, F64Deserializer};
use serde::de::{Deserialize, DeserializeOwned, Deserializer, IntoDeserializer};
use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, Configure, Token};
@@ -832,6 +833,26 @@ fn test_f64() {
test(1.11, &[Token::F64(1.11)]);
}
#[test]
fn test_nan() {
let f32_deserializer = F32Deserializer::<serde::de::value::Error>::new;
let f64_deserializer = F64Deserializer::<serde::de::value::Error>::new;
let pos_f32_nan = f32_deserializer(f32::NAN.copysign(1.0));
let pos_f64_nan = f64_deserializer(f64::NAN.copysign(1.0));
assert!(f32::deserialize(pos_f32_nan).unwrap().is_sign_positive());
assert!(f32::deserialize(pos_f64_nan).unwrap().is_sign_positive());
assert!(f64::deserialize(pos_f32_nan).unwrap().is_sign_positive());
assert!(f64::deserialize(pos_f64_nan).unwrap().is_sign_positive());
let neg_f32_nan = f32_deserializer(f32::NAN.copysign(-1.0));
let neg_f64_nan = f64_deserializer(f64::NAN.copysign(-1.0));
assert!(f32::deserialize(neg_f32_nan).unwrap().is_sign_negative());
assert!(f32::deserialize(neg_f64_nan).unwrap().is_sign_negative());
assert!(f64::deserialize(neg_f32_nan).unwrap().is_sign_negative());
assert!(f64::deserialize(neg_f64_nan).unwrap().is_sign_negative());
}
#[test]
fn test_char() {
test('a', &[Token::Char('a')]);
@@ -2,10 +2,12 @@ error[E0609]: no field `b` on type `&remote::S`
--> tests/ui/remote/unknown_field.rs:12:5
|
12 | b: u8,
| ^ help: a field with a similar name exists: `a`
| ^ unknown field
error[E0560]: struct `remote::S` has no field named `b`
--> tests/ui/remote/unknown_field.rs:12:5
|
12 | b: u8,
| ^ help: a field with a similar name exists: `a`
| ^ `remote::S` does not have this field
|
= note: all struct fields are already assigned