diff options
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | Android.bp | 47 | ||||
-rw-r--r-- | Cargo.toml | 14 | ||||
-rw-r--r-- | Cargo.toml.orig | 5 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 23 | ||||
-rw-r--r-- | TEST_MAPPING | 97 | ||||
-rw-r--r-- | build.rs | 94 | ||||
-rw-r--r-- | cargo2android.json | 8 | ||||
-rw-r--r-- | crates-io.md | 23 | ||||
-rw-r--r-- | patches/Android.bp.patch | 13 | ||||
-rw-r--r-- | src/de/format.rs | 30 | ||||
-rw-r--r-- | src/de/impls.rs | 386 | ||||
-rw-r--r-- | src/de/mod.rs | 34 | ||||
-rw-r--r-- | src/integer128.rs | 4 | ||||
-rw-r--r-- | src/lib.rs | 30 | ||||
-rw-r--r-- | src/private/de.rs | 33 | ||||
-rw-r--r-- | src/private/mod.rs | 7 | ||||
-rw-r--r-- | src/ser/impls.rs | 21 | ||||
-rw-r--r-- | src/ser/mod.rs | 30 |
20 files changed, 578 insertions, 338 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 1eff8ec..5f68c60 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,6 @@ { "git": { - "sha1": "e9270e59f0c46817899dd61119674396f24c2b3e" - } -} + "sha1": "02bd79a0bada78dd88d050f6478806f001f41fb0" + }, + "path_in_vcs": "serde" +}
\ No newline at end of file @@ -42,6 +42,8 @@ rust_library { name: "libserde", host_supported: true, crate_name: "serde", + cargo_env_compat: true, + cargo_pkg_version: "1.0.136", srcs: ["src/lib.rs"], edition: "2015", features: [ @@ -50,33 +52,32 @@ rust_library { "serde_derive", "std", ], - cfgs: [ - "core_duration", - "core_reverse", - "core_try_from", - "de_boxed_c_str", - "de_boxed_path", - "de_rc_dst", - "integer128", - "num_nonzero", - "num_nonzero_signed", - "ops_bound", - "range_inclusive", - "serde_derive", - "std_atomic", - // "std_atomic64", // not for arm/arm64 - "systemtime_checked_add", - ], proc_macros: ["libserde_derive"], apex_available: [ "//apex_available:platform", "com.android.virt", ], + vendor_available: true, } -// dependent_library ["feature_list"] -// proc-macro2-1.0.26 "default,proc-macro" -// quote-1.0.9 "default,proc-macro" -// serde_derive-1.0.125 "default" -// syn-1.0.71 "clone-impls,default,derive,parsing,printing,proc-macro,quote" -// unicode-xid-0.2.1 "default" +rust_test { + name: "serde_test_src_lib", + host_supported: true, + crate_name: "serde", + cargo_env_compat: true, + cargo_pkg_version: "1.0.136", + srcs: ["src/lib.rs"], + test_suites: ["general-tests"], + auto_gen_config: true, + test_options: { + unit_test: true, + }, + edition: "2015", + features: [ + "default", + "derive", + "serde_derive", + "std", + ], + proc_macros: ["libserde_derive"], +} @@ -3,16 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] +rust-version = "1.15" name = "serde" -version = "1.0.125" +version = "1.0.136" authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] build = "build.rs" include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] @@ -30,7 +30,7 @@ targets = ["x86_64-unknown-linux-gnu"] [package.metadata.playground] features = ["derive", "rc"] [dependencies.serde_derive] -version = "=1.0.125" +version = "=1.0.136" optional = true [dev-dependencies.serde_derive] version = "1.0" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 6488d90..2cf4ca4 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,7 +1,8 @@ [package] name = "serde" -version = "1.0.125" # remember to update html_root_url and serde_derive dependency +version = "1.0.136" # remember to update html_root_url and serde_derive dependency authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] +rust-version = "1.15" license = "MIT OR Apache-2.0" description = "A generic serialization/deserialization framework" homepage = "https://serde.rs" @@ -14,7 +15,7 @@ include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APAC build = "build.rs" [dependencies] -serde_derive = { version = "=1.0.125", optional = true, path = "../serde_derive" } +serde_derive = { version = "=1.0.136", optional = true, path = "../serde_derive" } [dev-dependencies] serde_derive = { version = "1.0", path = "../serde_derive" } @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/serde/serde-1.0.125.crate" + value: "https://static.crates.io/crates/serde/serde-1.0.136.crate" } - version: "1.0.125" + version: "1.0.136" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 4 - day: 13 + year: 2022 + month: 3 + day: 1 } } @@ -77,17 +77,20 @@ fn main() { Serde is one of the most widely used Rust libraries so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the -[#general] or [#beginners] channels of the unofficial community Discord, the -[#rust-usage] channel of the official Rust Project Discord, or the -[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag -on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned -weekly easy questions post, or the Rust [Discourse forum][discourse]. It's -acceptable to file a support issue in this repo but they tend not to get as many -eyes as any of the above and may get closed without a response after some time. - -[#general]: https://discord.com/channels/273534239310479360/274215136414400513 -[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or +[#beginners] channels of the official Rust Project Discord (invite: +<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general [stackoverflow]: https://stackoverflow.com/questions/tagged/rust [/r/rust]: https://www.reddit.com/r/rust diff --git a/TEST_MAPPING b/TEST_MAPPING index b835c6b..bec5d80 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,53 +1,120 @@ // Generated by update_crate_tests.py for tests that depend on this crate. { + "imports": [ + { + "path": "external/rust/crates/base64" + }, + { + "path": "external/rust/crates/bitflags" + }, + { + "path": "external/rust/crates/bytes" + }, + { + "path": "external/rust/crates/either" + }, + { + "path": "external/rust/crates/rand_chacha" + }, + { + "path": "external/rust/crates/serde-xml-rs" + }, + { + "path": "external/rust/crates/serde_cbor" + }, + { + "path": "external/rust/crates/slab" + }, + { + "path": "external/rust/crates/tinytemplate" + }, + { + "path": "external/rust/crates/tinyvec" + }, + { + "path": "external/rust/crates/unicode-bidi" + }, + { + "path": "external/rust/crates/unicode-xid" + }, + { + "path": "external/rust/crates/url" + } + ], "presubmit": [ { + "name": "ZipFuseTest" + }, + { + "name": "apkdmverity.test" + }, + { "name": "authfs_device_test_src_lib" }, { - "name": "either_device_test_src_lib" + "name": "diced_test" }, { - "name": "serde_cbor_device_test_src_lib" + "name": "diced_vendor_test" }, { - "name": "serde_cbor_device_test_tests_bennofs" + "name": "keystore2_test" }, { - "name": "serde_cbor_device_test_tests_canonical" + "name": "keystore2_test_utils_test" }, { - "name": "serde_cbor_device_test_tests_de" + "name": "legacykeystore_test" }, { - "name": "serde_cbor_device_test_tests_enum" + "name": "libcert_request_validator_tests" + }, + { + "name": "microdroid_manager_test" + }, + { + "name": "serde_test_src_lib" + }, + { + "name": "virtualizationservice_device_test" + } + ], + "presubmit-rust": [ + { + "name": "ZipFuseTest" + }, + { + "name": "apkdmverity.test" + }, + { + "name": "authfs_device_test_src_lib" }, { - "name": "serde_cbor_device_test_tests_ser" + "name": "diced_test" }, { - "name": "serde_cbor_device_test_tests_std_types" + "name": "diced_vendor_test" }, { - "name": "serde_cbor_device_test_tests_tags" + "name": "keystore2_test" }, { - "name": "serde_cbor_device_test_tests_value" + "name": "keystore2_test_utils_test" }, { - "name": "serde_test_device_test_src_lib" + "name": "legacykeystore_test" }, { - "name": "unicode-bidi_device_test_src_lib" + "name": "libcert_request_validator_tests" }, { - "name": "url_device_test_src_lib" + "name": "microdroid_manager_test" }, { - "name": "url_device_test_tests_data" + "name": "serde_test_src_lib" }, { - "name": "url_device_test_tests_unit" + "name": "virtualizationservice_device_test" } ] } @@ -17,90 +17,96 @@ fn main() { // std::collections::Bound was stabilized in Rust 1.17 // but it was moved to core::ops later in Rust 1.26: // https://doc.rust-lang.org/core/ops/enum.Bound.html - if minor >= 26 { - println!("cargo:rustc-cfg=ops_bound"); - } else if minor >= 17 && cfg!(feature = "std") { - println!("cargo:rustc-cfg=collections_bound"); + if minor < 26 { + println!("cargo:rustc-cfg=no_ops_bound"); + if minor < 17 { + println!("cargo:rustc-cfg=no_collections_bound"); + } } // core::cmp::Reverse stabilized in Rust 1.19: // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html - if minor >= 19 { - println!("cargo:rustc-cfg=core_reverse"); + if minor < 19 { + println!("cargo:rustc-cfg=no_core_reverse"); } // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path - if minor >= 20 { - println!("cargo:rustc-cfg=de_boxed_c_str"); - println!("cargo:rustc-cfg=de_boxed_path"); + if minor < 20 { + println!("cargo:rustc-cfg=no_de_boxed_c_str"); + println!("cargo:rustc-cfg=no_de_boxed_path"); } // From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21: // https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>> // https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>> - if minor >= 21 { - println!("cargo:rustc-cfg=de_rc_dst"); + if minor < 21 { + println!("cargo:rustc-cfg=no_de_rc_dst"); } // Duration available in core since Rust 1.25: // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations - if minor >= 25 { - println!("cargo:rustc-cfg=core_duration"); + if minor < 25 { + println!("cargo:rustc-cfg=no_core_duration"); } // 128-bit integers stabilized in Rust 1.26: // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html // - // Disabled on Emscripten targets as Emscripten doesn't - // currently support integers larger than 64 bits. - if minor >= 26 && !emscripten { - println!("cargo:rustc-cfg=integer128"); + // 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 minor < 26 || emscripten && minor < 40 { + println!("cargo:rustc-cfg=no_integer128"); } // Inclusive ranges methods stabilized in Rust 1.27: // https://github.com/rust-lang/rust/pull/50758 - if minor >= 27 { - println!("cargo:rustc-cfg=range_inclusive"); + // Also Iterator::try_for_each: + // https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations + if minor < 27 { + println!("cargo:rustc-cfg=no_range_inclusive"); + println!("cargo:rustc-cfg=no_iterator_try_fold"); } // Non-zero integers stabilized in Rust 1.28: // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations - if minor >= 28 { - println!("cargo:rustc-cfg=num_nonzero"); + if minor < 28 { + println!("cargo:rustc-cfg=no_num_nonzero"); } // Current minimum supported version of serde_derive crate is Rust 1.31. - if minor >= 31 { - println!("cargo:rustc-cfg=serde_derive"); + if minor < 31 { + println!("cargo:rustc-cfg=no_serde_derive"); } // 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=core_try_from"); - println!("cargo:rustc-cfg=num_nonzero_signed"); - println!("cargo:rustc-cfg=systemtime_checked_add"); - - // Whitelist of archs that support std::sync::atomic module. Ideally we - // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. - // Instead this is based on rustc's src/librustc_target/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"); - let has_atomic32 = has_atomic64 || emscripten; - if has_atomic64 { - println!("cargo:rustc-cfg=std_atomic64"); - } - if has_atomic32 { - println!("cargo:rustc-cfg=std_atomic"); - } + 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"); + } + + // Whitelist of archs that support std::sync::atomic module. Ideally we + // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. + // Instead 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"); } } diff --git a/cargo2android.json b/cargo2android.json index 4e40fcb..2a35106 100644 --- a/cargo2android.json +++ b/cargo2android.json @@ -3,9 +3,13 @@ "//apex_available:platform", "com.android.virt" ], + "cfg-blocklist": [ + "std_atomic64" + ], "dependencies": true, "device": true, "features": "default,derive", - "patch": "patches/Android.bp.patch", - "run": true + "run": true, + "tests": true, + "vendor-available": true }
\ No newline at end of file diff --git a/crates-io.md b/crates-io.md index 0775761..b57bc5f 100644 --- a/crates-io.md +++ b/crates-io.md @@ -45,17 +45,20 @@ fn main() { Serde is one of the most widely used Rust libraries so any place that Rustaceans congregate will be able to help you out. For chat, consider trying the -[#general] or [#beginners] channels of the unofficial community Discord, the -[#rust-usage] channel of the official Rust Project Discord, or the -[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag -on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned -weekly easy questions post, or the Rust [Discourse forum][discourse]. It's -acceptable to file a support issue in this repo but they tend not to get as many -eyes as any of the above and may get closed without a response after some time. - -[#general]: https://discord.com/channels/273534239310479360/274215136414400513 -[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281 +[#rust-questions] or [#rust-beginners] channels of the unofficial community +Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or +[#beginners] channels of the official Rust Project Discord (invite: +<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For +asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the +[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust +[Discourse forum][discourse]. It's acceptable to file a support issue in this +repo but they tend not to get as many eyes as any of the above and may get +closed without a response after some time. + +[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 +[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 +[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general [stackoverflow]: https://stackoverflow.com/questions/tagged/rust [/r/rust]: https://www.reddit.com/r/rust diff --git a/patches/Android.bp.patch b/patches/Android.bp.patch deleted file mode 100644 index 071947f..0000000 --- a/patches/Android.bp.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git b/Android.bp a/Android.bp -index 41d67cc..277296f 100644 ---- b/Android.bp -+++ a/Android.bp -@@ -64,7 +64,7 @@ - "range_inclusive", - "serde_derive", - "std_atomic", -- "std_atomic64", -+ // "std_atomic64", // not for arm/arm64 - "systemtime_checked_add", - ], - proc_macros: ["libserde_derive"], diff --git a/src/de/format.rs b/src/de/format.rs new file mode 100644 index 0000000..58ec096 --- /dev/null +++ b/src/de/format.rs @@ -0,0 +1,30 @@ +use lib::fmt::{self, Write}; +use lib::str; + +pub struct Buf<'a> { + bytes: &'a mut [u8], + offset: usize, +} + +impl<'a> Buf<'a> { + pub fn new(bytes: &'a mut [u8]) -> Self { + Buf { bytes, offset: 0 } + } + + pub fn as_str(&self) -> &str { + let slice = &self.bytes[..self.offset]; + unsafe { str::from_utf8_unchecked(slice) } + } +} + +impl<'a> Write for Buf<'a> { + fn write_str(&mut self, s: &str) -> fmt::Result { + if self.offset + s.len() > self.bytes.len() { + Err(fmt::Error) + } else { + self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes()); + self.offset += s.len(); + Ok(()) + } + } +} diff --git a/src/de/impls.rs b/src/de/impls.rs index 59d90d2..c5aaca7 100644 --- a/src/de/impls.rs +++ b/src/de/impls.rs @@ -4,7 +4,7 @@ use de::{ Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor, }; -#[cfg(any(core_duration, feature = "std", feature = "alloc"))] +#[cfg(any(feature = "std", feature = "alloc", not(no_core_duration)))] use de::MapAccess; use seed::InPlaceSeed; @@ -81,8 +81,34 @@ impl<'de> Deserialize<'de> for bool { //////////////////////////////////////////////////////////////////////////////// macro_rules! impl_deserialize_num { - ($ty:ident, $deserialize:ident $($methods:tt)*) => { - impl<'de> Deserialize<'de> for $ty { + ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => { + impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*); + + #[cfg(all(not(no_num_nonzero), $($($cfg)*)*))] + impl<'de> Deserialize<'de> for num::$nonzero { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + struct NonZeroVisitor; + + impl<'de> Visitor<'de> for NonZeroVisitor { + type Value = num::$nonzero; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str(concat!("a nonzero ", stringify!($primitive))) + } + + $($($method!(nonzero $primitive $val : $visit);)*)* + } + + deserializer.$deserialize(NonZeroVisitor) + } + } + }; + + ($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => { + impl<'de> Deserialize<'de> for $primitive { #[inline] fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where @@ -91,13 +117,13 @@ macro_rules! impl_deserialize_num { struct PrimitiveVisitor; impl<'de> Visitor<'de> for PrimitiveVisitor { - type Value = $ty; + type Value = $primitive; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str(stringify!($ty)) + formatter.write_str(stringify!($primitive)) } - $($methods)* + $($($method!($val : $visit);)*)* } deserializer.$deserialize(PrimitiveVisitor) @@ -116,85 +142,149 @@ macro_rules! num_self { Ok(v) } }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + where + E: Error, + { + if let Some(nonzero) = Self::Value::new(v) { + Ok(nonzero) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(0), &self)) + } + } + }; } macro_rules! num_as_self { - ($($ty:ident : $visit:ident)*) => { - $( - #[inline] - fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> - where - E: Error, - { - Ok(v as Self::Value) + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + where + E: Error, + { + Ok(v as Self::Value) + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + where + E: Error, + { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + Ok(nonzero) + } else { + Err(Error::invalid_value(Unexpected::Unsigned(0), &self)) } - )* + } }; } macro_rules! int_to_int { - ($($ty:ident : $visit:ident)*) => { - $( - #[inline] - fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> - where - E: Error, + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + where + E: Error, + { + if Self::Value::min_value() as i64 <= v as i64 + && v as i64 <= Self::Value::max_value() as i64 { - 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)) + Ok(v as Self::Value) + } else { + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + 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) { + return Ok(nonzero); } } - )* + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } }; } macro_rules! int_to_uint { - ($($ty:ident : $visit:ident)*) => { - $( - #[inline] - fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> - 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)) + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + 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)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + 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); } } - )* + Err(Error::invalid_value(Unexpected::Signed(v as i64), &self)) + } }; } macro_rules! uint_to_self { - ($($ty:ident : $visit:ident)*) => { - $( - #[inline] - fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> - 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)) + ($ty:ident : $visit:ident) => { + #[inline] + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + 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)) + } + } + }; + + (nonzero $primitive:ident $ty:ident : $visit:ident) => { + fn $visit<E>(self, v: $ty) -> Result<Self::Value, E> + where + E: Error, + { + if v as u64 <= $primitive::max_value() as u64 { + if let Some(nonzero) = Self::Value::new(v as $primitive) { + return Ok(nonzero); } } - )* + Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self)) + } }; } impl_deserialize_num! { - i8, deserialize_i8 + i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), 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, deserialize_i16 + i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16 num_self!(i16:visit_i16); num_as_self!(i8:visit_i8); int_to_int!(i32:visit_i32 i64:visit_i64); @@ -202,7 +292,7 @@ impl_deserialize_num! { } impl_deserialize_num! { - i32, deserialize_i32 + i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32 num_self!(i32:visit_i32); num_as_self!(i8:visit_i8 i16:visit_i16); int_to_int!(i64:visit_i64); @@ -210,28 +300,28 @@ impl_deserialize_num! { } impl_deserialize_num! { - i64, deserialize_i64 + i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), 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, deserialize_i64 + isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), 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); } impl_deserialize_num! { - u8, deserialize_u8 + u8, NonZeroU8, deserialize_u8 num_self!(u8:visit_u8); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64); } impl_deserialize_num! { - u16, deserialize_u16 + u16, NonZeroU16, deserialize_u16 num_self!(u16:visit_u16); num_as_self!(u8:visit_u8); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); @@ -239,7 +329,7 @@ impl_deserialize_num! { } impl_deserialize_num! { - u32, deserialize_u32 + u32, NonZeroU32, deserialize_u32 num_self!(u32:visit_u32); num_as_self!(u8:visit_u8 u16:visit_u16); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); @@ -247,14 +337,14 @@ impl_deserialize_num! { } impl_deserialize_num! { - u64, deserialize_u64 + u64, NonZeroU64, deserialize_u64 num_self!(u64:visit_u64); num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); } impl_deserialize_num! { - usize, deserialize_u64 + usize, NonZeroUsize, deserialize_u64 num_as_self!(u8:visit_u8 u16:visit_u16); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); uint_to_self!(u32:visit_u32 u64:visit_u64); @@ -277,42 +367,62 @@ impl_deserialize_num! { } serde_if_integer128! { + 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 + { + 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, + { + 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)) + } + } else { + Err(Error::invalid_value( + Unexpected::Other(stringify!($ty)), + &self, + )) + } + } + }; + } + impl_deserialize_num! { - i128, deserialize_i128 + 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); - - #[inline] - fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E> - where - E: Error, - { - if v <= i128::max_value() as u128 { - Ok(v as i128) - } else { - Err(Error::invalid_value(Unexpected::Other("u128"), &self)) - } - } + num_128!(u128:visit_u128); } impl_deserialize_num! { - u128, deserialize_u128 + 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); - - #[inline] - fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E> - where - E: Error, - { - if 0 <= v { - Ok(v as u128) - } else { - Err(Error::invalid_value(Unexpected::Other("i128"), &self)) - } - } + num_128!(i128:visit_i128); } } @@ -637,10 +747,10 @@ macro_rules! forwarded_impl { } } -#[cfg(all(feature = "std", de_boxed_c_str))] +#[cfg(all(feature = "std", not(no_de_boxed_c_str)))] forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str); -#[cfg(core_reverse)] +#[cfg(not(no_core_reverse))] forwarded_impl!((T), Reverse<T>, Reverse); //////////////////////////////////////////////////////////////////////////////// @@ -1604,7 +1714,7 @@ impl<'de> Deserialize<'de> for PathBuf { } } -#[cfg(all(feature = "std", de_boxed_path))] +#[cfg(all(feature = "std", not(no_de_boxed_path)))] forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path); //////////////////////////////////////////////////////////////////////////////// @@ -1685,11 +1795,7 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice); #[cfg(any(feature = "std", feature = "alloc"))] forwarded_impl!((), Box<str>, String::into_boxed_str); -#[cfg(all( - not(de_rc_dst), - feature = "rc", - any(feature = "std", feature = "alloc") -))] +#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] forwarded_impl! { /// This impl requires the [`"rc"`] Cargo feature of Serde. /// @@ -1701,11 +1807,7 @@ forwarded_impl! { (T), Arc<T>, Arc::new } -#[cfg(all( - not(de_rc_dst), - feature = "rc", - any(feature = "std", feature = "alloc") -))] +#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] forwarded_impl! { /// This impl requires the [`"rc"`] Cargo feature of Serde. /// @@ -1772,7 +1874,11 @@ where //////////////////////////////////////////////////////////////////////////////// -#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg(all( + not(no_de_rc_dst), + feature = "rc", + any(feature = "std", feature = "alloc") +))] macro_rules! box_forwarded_impl { ( $(#[doc = $doc:tt])* @@ -1793,7 +1899,11 @@ macro_rules! box_forwarded_impl { }; } -#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg(all( + not(no_de_rc_dst), + feature = "rc", + any(feature = "std", feature = "alloc") +))] box_forwarded_impl! { /// This impl requires the [`"rc"`] Cargo feature of Serde. /// @@ -1805,7 +1915,11 @@ box_forwarded_impl! { Rc } -#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))] +#[cfg(all( + not(no_de_rc_dst), + feature = "rc", + any(feature = "std", feature = "alloc") +))] box_forwarded_impl! { /// This impl requires the [`"rc"`] Cargo feature of Serde. /// @@ -1849,7 +1963,7 @@ forwarded_impl!((T), RwLock<T>, RwLock::new); // secs: u64, // nanos: u32, // } -#[cfg(any(core_duration, feature = "std"))] +#[cfg(any(feature = "std", not(no_core_duration)))] impl<'de> Deserialize<'de> for Duration { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where @@ -2127,11 +2241,11 @@ impl<'de> Deserialize<'de> for SystemTime { const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"]; let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)); - #[cfg(systemtime_checked_add)] + #[cfg(not(no_systemtime_checked_add))] let ret = UNIX_EPOCH .checked_add(duration) .ok_or_else(|| D::Error::custom("overflow deserializing SystemTime")); - #[cfg(not(systemtime_checked_add))] + #[cfg(no_systemtime_checked_add)] let ret = Ok(UNIX_EPOCH + duration); ret } @@ -2167,7 +2281,7 @@ where } } -#[cfg(range_inclusive)] +#[cfg(not(no_range_inclusive))] impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx> where Idx: Deserialize<'de>, @@ -2319,7 +2433,7 @@ mod range { //////////////////////////////////////////////////////////////////////////////// -#[cfg(any(ops_bound, collections_bound))] +#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))] impl<'de, T> Deserialize<'de> for Bound<T> where T: Deserialize<'de>, @@ -2427,58 +2541,6 @@ where //////////////////////////////////////////////////////////////////////////////// -macro_rules! nonzero_integers { - ( $( $T: ident, )+ ) => { - $( - #[cfg(num_nonzero)] - impl<'de> Deserialize<'de> for num::$T { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: Deserializer<'de>, - { - let value = try!(Deserialize::deserialize(deserializer)); - match <num::$T>::new(value) { - Some(nonzero) => Ok(nonzero), - None => Err(Error::custom("expected a non-zero value")), - } - } - } - )+ - }; -} - -nonzero_integers! { - NonZeroU8, - NonZeroU16, - NonZeroU32, - NonZeroU64, - NonZeroUsize, -} - -#[cfg(num_nonzero_signed)] -nonzero_integers! { - NonZeroI8, - NonZeroI16, - NonZeroI32, - NonZeroI64, - NonZeroIsize, -} - -// Currently 128-bit integers do not work on Emscripten targets so we need an -// additional `#[cfg]` -serde_if_integer128! { - nonzero_integers! { - NonZeroU128, - } - - #[cfg(num_nonzero_signed)] - nonzero_integers! { - NonZeroI128, - } -} - -//////////////////////////////////////////////////////////////////////////////// - impl<'de, T, E> Deserialize<'de> for Result<T, E> where T: Deserialize<'de>, @@ -2599,7 +2661,7 @@ where } } -#[cfg(all(feature = "std", std_atomic))] +#[cfg(all(feature = "std", not(no_std_atomic)))] macro_rules! atomic_impl { ($($ty:ident)*) => { $( @@ -2615,14 +2677,14 @@ macro_rules! atomic_impl { }; } -#[cfg(all(feature = "std", std_atomic))] +#[cfg(all(feature = "std", not(no_std_atomic)))] atomic_impl! { AtomicBool AtomicI8 AtomicI16 AtomicI32 AtomicIsize AtomicU8 AtomicU16 AtomicU32 AtomicUsize } -#[cfg(all(feature = "std", std_atomic64))] +#[cfg(all(feature = "std", not(no_std_atomic64)))] atomic_impl! { AtomicI64 AtomicU64 } diff --git a/src/de/mod.rs b/src/de/mod.rs index 1ed7b4f..4ae4773 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -118,6 +118,8 @@ use lib::*; pub mod value; +#[cfg(not(no_integer128))] +mod format; mod ignored_any; mod impls; mod utf8; @@ -1007,7 +1009,7 @@ pub trait Deserializer<'de>: Sized { /// `Deserializer`. /// /// If the `Visitor` would benefit from taking ownership of `String` data, - /// indiciate this to the `Deserializer` by using `deserialize_string` + /// indicate this to the `Deserializer` by using `deserialize_string` /// instead. fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where @@ -1213,6 +1215,20 @@ pub trait Deserializer<'de>: Sized { fn is_human_readable(&self) -> bool { true } + + // Not public API. + #[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] + #[doc(hidden)] + fn __deserialize_content<V>( + self, + _: ::actually_private::T, + visitor: V, + ) -> Result<::private::de::Content<'de>, Self::Error> + where + V: Visitor<'de, Value = ::private::de::Content<'de>>, + { + self.deserialize_any(visitor) + } } //////////////////////////////////////////////////////////////////////////////// @@ -1352,8 +1368,10 @@ pub trait Visitor<'de>: Sized { where E: Error, { - let _ = v; - Err(Error::invalid_type(Unexpected::Other("i128"), &self)) + 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)) } } @@ -1412,8 +1430,10 @@ pub trait Visitor<'de>: Sized { where E: Error, { - let _ = v; - Err(Error::invalid_type(Unexpected::Other("u128"), &self)) + 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)) } } @@ -1714,7 +1734,7 @@ pub trait SeqAccess<'de> { } } -impl<'de, 'a, A> SeqAccess<'de> for &'a mut A +impl<'de, 'a, A: ?Sized> SeqAccess<'de> for &'a mut A where A: SeqAccess<'de>, { @@ -1867,7 +1887,7 @@ pub trait MapAccess<'de> { } } -impl<'de, 'a, A> MapAccess<'de> for &'a mut A +impl<'de, 'a, A: ?Sized> MapAccess<'de> for &'a mut A where A: MapAccess<'de>, { diff --git a/src/integer128.rs b/src/integer128.rs index 0ee05bd..904c2a2 100644 --- a/src/integer128.rs +++ b/src/integer128.rs @@ -66,7 +66,7 @@ /// ($($tt:tt)*) => {}; /// } /// ``` -#[cfg(integer128)] +#[cfg(not(no_integer128))] #[macro_export] macro_rules! serde_if_integer128 { ($($tt:tt)*) => { @@ -74,7 +74,7 @@ macro_rules! serde_if_integer128 { }; } -#[cfg(not(integer128))] +#[cfg(no_integer128)] #[macro_export] #[doc(hidden)] macro_rules! serde_if_integer128 { @@ -60,7 +60,7 @@ //! //! [JSON]: https://github.com/serde-rs/json //! [Bincode]: https://github.com/servo/bincode -//! [CBOR]: https://github.com/pyfisch/cbor +//! [CBOR]: https://github.com/enarx/ciborium //! [YAML]: https://github.com/dtolnay/serde-yaml //! [MessagePack]: https://github.com/3Hren/msgpack-rust //! [TOML]: https://github.com/alexcrichton/toml-rs @@ -73,7 +73,7 @@ //! [URL]: https://docs.rs/serde_qs //! [Envy]: https://github.com/softprops/envy //! [Envy Store]: https://github.com/softprops/envy-store -//! [Cargo]: http://doc.crates.io/manifest.html +//! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html //! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html //! [S-expressions]: https://github.com/rotty/lexpr-rs //! [D-Bus]: https://docs.rs/zvariant @@ -84,7 +84,7 @@ //////////////////////////////////////////////////////////////////////////////// // Serde types in rustdoc of other crates get linked to here. -#![doc(html_root_url = "https://docs.rs/serde/1.0.125")] +#![doc(html_root_url = "https://docs.rs/serde/1.0.136")] // 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 @@ -94,13 +94,14 @@ #![cfg_attr(feature = "unstable", feature(never_type))] #![allow(unknown_lints, bare_trait_objects, deprecated)] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] -#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] // Ignored clippy and clippy_pedantic lints #![cfg_attr( feature = "cargo-clippy", allow( // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 unnested_or_patterns, + // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768 + semicolon_if_nothing_returned, // not available in our oldest supported compiler checked_conversions, empty_enum, @@ -157,7 +158,7 @@ mod lib { pub use std::*; } - pub use self::core::{cmp, iter, mem, num, slice, str}; + 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::{u16, u32, u64, u8, usize}; @@ -226,27 +227,27 @@ mod lib { #[cfg(feature = "std")] pub use std::time::{SystemTime, UNIX_EPOCH}; - #[cfg(all(feature = "std", collections_bound))] + #[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))] pub use std::collections::Bound; - #[cfg(core_reverse)] + #[cfg(not(no_core_reverse))] pub use self::core::cmp::Reverse; - #[cfg(ops_bound)] + #[cfg(not(no_ops_bound))] pub use self::core::ops::Bound; - #[cfg(range_inclusive)] + #[cfg(not(no_range_inclusive))] pub use self::core::ops::RangeInclusive; - #[cfg(all(feature = "std", std_atomic))] + #[cfg(all(feature = "std", not(no_std_atomic)))] pub use std::sync::atomic::{ AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, AtomicUsize, Ordering, }; - #[cfg(all(feature = "std", std_atomic64))] + #[cfg(all(feature = "std", not(no_std_atomic64)))] pub use std::sync::atomic::{AtomicI64, AtomicU64}; - #[cfg(any(core_duration, feature = "std"))] + #[cfg(any(feature = "std", not(no_core_duration)))] pub use self::core::time::Duration; } @@ -294,3 +295,8 @@ extern crate serde_derive; #[cfg(feature = "serde_derive")] #[doc(hidden)] pub use serde_derive::*; + +#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))] +mod actually_private { + pub struct T; +} diff --git a/src/private/de.rs b/src/private/de.rs index 9199816..f0697d6 100644 --- a/src/private/de.rs +++ b/src/private/de.rs @@ -206,6 +206,7 @@ mod content { use lib::*; use __private::size_hint; + use actually_private; use de::{ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor, @@ -215,7 +216,7 @@ mod content { /// deserializing untagged enums and internally tagged enums. /// /// Not public API. Use serde-value instead. - #[derive(Debug)] + #[derive(Debug, Clone)] pub enum Content<'de> { Bool(bool), @@ -294,7 +295,7 @@ mod content { // Untagged and internally tagged enums are only supported in // self-describing formats. let visitor = ContentVisitor { value: PhantomData }; - deserializer.deserialize_any(visitor) + deserializer.__deserialize_content(actually_private::T, visitor) } } @@ -1427,6 +1428,18 @@ mod content { drop(self); visitor.visit_unit() } + + fn __deserialize_content<V>( + self, + _: actually_private::T, + visitor: V, + ) -> Result<Content<'de>, Self::Error> + where + V: Visitor<'de, Value = Content<'de>>, + { + let _ = visitor; + Ok(self.content) + } } impl<'de, E> ContentDeserializer<'de, E> { @@ -2138,6 +2151,18 @@ mod content { { visitor.visit_unit() } + + fn __deserialize_content<V>( + self, + _: actually_private::T, + visitor: V, + ) -> Result<Content<'de>, Self::Error> + where + V: Visitor<'de, Value = Content<'de>>, + { + let _ = visitor; + Ok(self.content.clone()) + } } impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> { @@ -2832,7 +2857,7 @@ where where T: DeserializeSeed<'de>, { - while let Some(item) = self.iter.next() { + for item in &mut self.iter { // Items in the vector are nulled out when used by a struct. if let Some((ref key, ref content)) = *item { self.pending_content = Some(content); @@ -2934,7 +2959,7 @@ where where T: DeserializeSeed<'de>, { - while let Some(item) = self.iter.next() { + for item in &mut self.iter { if let Some((ref key, ref content)) = *item { // Do not take(), instead borrow this entry. The internally tagged // enum does its own buffering so we can't tell whether this entry diff --git a/src/private/mod.rs b/src/private/mod.rs index 24ea84b..e896902 100644 --- a/src/private/mod.rs +++ b/src/private/mod.rs @@ -1,6 +1,6 @@ -#[cfg(serde_derive)] +#[cfg(not(no_serde_derive))] pub mod de; -#[cfg(serde_derive)] +#[cfg(not(no_serde_derive))] pub mod ser; pub mod size_hint; @@ -14,6 +14,7 @@ pub use lib::default::Default; pub use lib::fmt::{self, Formatter}; pub use lib::marker::PhantomData; pub use lib::option::Option::{self, None, Some}; +pub use lib::ptr; pub use lib::result::Result::{self, Err, Ok}; pub use self::string::from_utf8_lossy; @@ -21,7 +22,7 @@ pub use self::string::from_utf8_lossy; #[cfg(any(feature = "alloc", feature = "std"))] pub use lib::{ToString, Vec}; -#[cfg(core_try_from)] +#[cfg(not(no_core_try_from))] pub use lib::convert::TryFrom; mod string { diff --git a/src/ser/impls.rs b/src/ser/impls.rs index c254ac6..7219f51 100644 --- a/src/ser/impls.rs +++ b/src/ser/impls.rs @@ -239,7 +239,7 @@ where //////////////////////////////////////////////////////////////////////////////// -#[cfg(range_inclusive)] +#[cfg(not(no_range_inclusive))] impl<Idx> Serialize for RangeInclusive<Idx> where Idx: Serialize, @@ -258,7 +258,7 @@ where //////////////////////////////////////////////////////////////////////////////// -#[cfg(any(ops_bound, collections_bound))] +#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))] impl<T> Serialize for Bound<T> where T: Serialize, @@ -467,7 +467,7 @@ where macro_rules! nonzero_integers { ( $( $T: ident, )+ ) => { $( - #[cfg(num_nonzero)] + #[cfg(not(no_num_nonzero))] impl Serialize for num::$T { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where @@ -488,7 +488,7 @@ nonzero_integers! { NonZeroUsize, } -#[cfg(num_nonzero_signed)] +#[cfg(not(no_num_nonzero_signed))] nonzero_integers! { NonZeroI8, NonZeroI16, @@ -504,7 +504,7 @@ serde_if_integer128! { NonZeroU128, } - #[cfg(num_nonzero_signed)] + #[cfg(not(no_num_nonzero_signed))] nonzero_integers! { NonZeroI128, } @@ -591,7 +591,7 @@ where //////////////////////////////////////////////////////////////////////////////// -#[cfg(any(core_duration, feature = "std"))] +#[cfg(any(feature = "std", not(no_core_duration)))] impl Serialize for Duration { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where @@ -890,7 +890,7 @@ where } } -#[cfg(core_reverse)] +#[cfg(not(no_core_reverse))] impl<T> Serialize for Reverse<T> where T: Serialize, @@ -906,7 +906,7 @@ where //////////////////////////////////////////////////////////////////////////////// -#[cfg(all(feature = "std", std_atomic))] +#[cfg(all(feature = "std", not(no_std_atomic)))] macro_rules! atomic_impl { ($($ty:ident)*) => { $( @@ -915,6 +915,7 @@ macro_rules! atomic_impl { where S: Serializer, { + // Matches the atomic ordering used in libcore for the Debug impl self.load(Ordering::SeqCst).serialize(serializer) } } @@ -922,14 +923,14 @@ macro_rules! atomic_impl { } } -#[cfg(all(feature = "std", std_atomic))] +#[cfg(all(feature = "std", not(no_std_atomic)))] atomic_impl! { AtomicBool AtomicI8 AtomicI16 AtomicI32 AtomicIsize AtomicU8 AtomicU16 AtomicU32 AtomicUsize } -#[cfg(all(feature = "std", std_atomic64))] +#[cfg(all(feature = "std", not(no_std_atomic64)))] atomic_impl! { AtomicI64 AtomicU64 } diff --git a/src/ser/mod.rs b/src/ser/mod.rs index d686c5a..dcf836b 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -1279,9 +1279,20 @@ pub trait Serializer: Sized { { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); - for item in iter { - try!(serializer.serialize_element(&item)); + + #[cfg(not(no_iterator_try_fold))] + { + let mut iter = iter; + try!(iter.try_for_each(|item| serializer.serialize_element(&item))); + } + + #[cfg(no_iterator_try_fold)] + { + for item in iter { + try!(serializer.serialize_element(&item)); + } } + serializer.end() } @@ -1319,9 +1330,20 @@ pub trait Serializer: Sized { { let iter = iter.into_iter(); let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter))); - for (key, value) in iter { - try!(serializer.serialize_entry(&key, &value)); + + #[cfg(not(no_iterator_try_fold))] + { + let mut iter = iter; + try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value))); + } + + #[cfg(no_iterator_try_fold)] + { + for (key, value) in iter { + try!(serializer.serialize_entry(&key, &value)); + } } + serializer.end() } |