aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2024-02-05 17:29:32 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-02-05 17:29:32 +0000
commit70b6b6924fde4a926a49249fe4398369ff6264b3 (patch)
tree5508bbb6a64c0fd6f0054b6a574f59a19b8b0802
parent80cd52f4a63605c3553dabdef55280ffbe93cdb2 (diff)
parente0994f6f353f7d26812aad5aa2a5d407b68e063f (diff)
downloadserde_yaml-70b6b6924fde4a926a49249fe4398369ff6264b3.tar.gz
Upgrade serde_yaml to 0.9.31 am: e0994f6f35HEADmastermain
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/serde_yaml/+/2949319 Change-Id: I09e6076e0bb6f50ccf95ad8639142a138488fcee Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--.github/workflows/ci.yml26
-rw-r--r--Android.bp2
-rw-r--r--Cargo.toml12
-rw-r--r--Cargo.toml.orig12
-rw-r--r--METADATA22
-rw-r--r--src/de.rs2
-rw-r--r--src/lib.rs7
-rw-r--r--src/libyaml/emitter.rs11
-rw-r--r--src/libyaml/error.rs26
-rw-r--r--src/libyaml/parser.rs29
-rw-r--r--src/mapping.rs120
-rw-r--r--src/number.rs28
-rw-r--r--tests/test_de.rs12
-rw-r--r--tests/test_error.rs69
-rw-r--r--tests/test_serde.rs16
-rw-r--r--tests/test_value.rs2
17 files changed, 251 insertions, 147 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index e5d0bcf..589f83a 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "f26dac4b3af3b2b90881604f917f2a75c7f1de0b"
+ "sha1": "2a77483b23897115bdd69af32ae34d593268d555"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b88154a..624334b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,7 +27,7 @@ jobs:
rust: [nightly, beta, stable, 1.64.0]
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -37,13 +37,27 @@ jobs:
- run: cargo build
- run: cargo test
+ doc:
+ name: Documentation
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ 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
+
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: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
@@ -54,7 +68,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: cargo miri test
@@ -68,7 +82,7 @@ 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
@@ -80,7 +94,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
- uses: dtolnay/install@cargo-fuzz
- run: cargo fuzz check
@@ -91,7 +105,7 @@ 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
- run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
diff --git a/Android.bp b/Android.bp
index 9c09f2f..ee5a8db 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5,7 +5,7 @@ rust_library_host {
name: "libserde_yaml",
crate_name: "serde_yaml",
cargo_env_compat: true,
- cargo_pkg_version: "0.9.25",
+ cargo_pkg_version: "0.9.31",
srcs: ["src/lib.rs"],
edition: "2021",
rustlibs: [
diff --git a/Cargo.toml b/Cargo.toml
index 65547c6..f8b42b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.64"
name = "serde_yaml"
-version = "0.9.25"
+version = "0.9.31"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "YAML data format for Serde"
documentation = "https://docs.rs/serde_yaml/"
@@ -38,7 +38,7 @@ targets = ["x86_64-unknown-linux-gnu"]
doc-scrape-examples = false
[dependencies.indexmap]
-version = "2"
+version = "2.2.1"
[dependencies.itoa]
version = "1.0"
@@ -47,16 +47,16 @@ version = "1.0"
version = "1.0"
[dependencies.serde]
-version = "1.0.139"
+version = "1.0.195"
[dependencies.unsafe-libyaml]
-version = "0.2.7"
+version = "0.2.10"
[dev-dependencies.anyhow]
-version = "1.0"
+version = "1.0.79"
[dev-dependencies.indoc]
version = "2.0"
[dev-dependencies.serde_derive]
-version = "1.0"
+version = "1.0.195"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index ce90b7b..a26b50e 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "serde_yaml"
-version = "0.9.25" # remember to update html_root_url
+version = "0.9.31"
authors = ["David Tolnay <dtolnay@gmail.com>"]
categories = ["encoding", "parser-implementations"]
description = "YAML data format for Serde"
@@ -12,16 +12,16 @@ repository = "https://github.com/dtolnay/serde-yaml"
rust-version = "1.64"
[dependencies]
-indexmap = "2"
+indexmap = "2.2.1"
itoa = "1.0"
ryu = "1.0"
-serde = "1.0.139"
-unsafe-libyaml = "0.2.7"
+serde = "1.0.195"
+unsafe-libyaml = "0.2.10"
[dev-dependencies]
-anyhow = "1.0"
+anyhow = "1.0.79"
indoc = "2.0"
-serde_derive = "1.0"
+serde_derive = "1.0.195"
[lib]
doc-scrape-examples = false
diff --git a/METADATA b/METADATA
index bb9e952..2c873f9 100644
--- a/METADATA
+++ b/METADATA
@@ -1,20 +1,24 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update external/rust/crates/serde_yaml
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
name: "serde_yaml"
description: "YAML data format for Serde"
third_party {
+ license_type: NOTICE
+ last_upgrade_date {
+ year: 2024
+ month: 2
+ day: 5
+ }
identifier {
type: "crates.io"
- value: "https://crates.io/crates/serde_yaml"
+ value: "https://static.crates.io/crates/serde_yaml/serde_yaml-0.9.31.crate"
+ version: "0.9.25"
}
identifier {
type: "Archive"
value: "https://static.crates.io/crates/serde_yaml/serde_yaml-0.9.25.crate"
- }
- version: "0.9.25"
- # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
- license_type: NOTICE
- last_upgrade_date {
- year: 2023
- month: 9
- day: 14
+ version: "0.9.31"
}
}
diff --git a/src/de.rs b/src/de.rs
index 43f4678..566f5f0 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -1079,7 +1079,7 @@ pub(crate) fn parse_f64(scalar: &str) -> Option<f64> {
return Some(f64::NEG_INFINITY);
}
if let ".nan" | ".NaN" | ".NAN" = scalar {
- return Some(f64::NAN);
+ return Some(f64::NAN.copysign(1.0));
}
if let Ok(float) = unpositive.parse::<f64>() {
if float.is_finite() {
diff --git a/src/lib.rs b/src/lib.rs
index d5256d4..7afcf93 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -115,8 +115,8 @@
//! }
//! ```
-#![doc(html_root_url = "https://docs.rs/serde_yaml/0.9.25")]
-#![deny(missing_docs)]
+#![doc(html_root_url = "https://docs.rs/serde_yaml/0.9.31")]
+#![deny(missing_docs, unsafe_op_in_unsafe_fn)]
// Suppressed clippy_pedantic lints
#![allow(
// buggy
@@ -134,11 +134,10 @@
clippy::match_same_arms,
clippy::module_name_repetitions,
clippy::needless_pass_by_value,
- clippy::option_if_let_else,
clippy::redundant_else,
clippy::single_match_else,
// code is acceptable
- clippy::blocks_in_if_conditions,
+ clippy::blocks_in_conditions,
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_precision_loss,
diff --git a/src/libyaml/emitter.rs b/src/libyaml/emitter.rs
index a0ce25f..686f06e 100644
--- a/src/libyaml/emitter.rs
+++ b/src/libyaml/emitter.rs
@@ -197,13 +197,14 @@ impl<'a> Emitter<'a> {
unsafe fn write_handler(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 {
let data = data.cast::<EmitterPinned>();
- match io::Write::write_all(
- &mut *(*data).write,
- slice::from_raw_parts(buffer, size as usize),
- ) {
+ match io::Write::write_all(unsafe { &mut *(*data).write }, unsafe {
+ slice::from_raw_parts(buffer, size as usize)
+ }) {
Ok(()) => 1,
Err(err) => {
- (*data).write_error = Some(err);
+ unsafe {
+ (*data).write_error = Some(err);
+ }
0
}
}
diff --git a/src/libyaml/error.rs b/src/libyaml/error.rs
index 603557d..8397f6e 100644
--- a/src/libyaml/error.rs
+++ b/src/libyaml/error.rs
@@ -18,41 +18,41 @@ pub(crate) struct Error {
impl Error {
pub unsafe fn parse_error(parser: *const sys::yaml_parser_t) -> Self {
Error {
- kind: (*parser).error,
- problem: match NonNull::new((*parser).problem as *mut _) {
- Some(problem) => CStr::from_ptr(problem),
+ kind: unsafe { (*parser).error },
+ problem: match NonNull::new(unsafe { (*parser).problem as *mut _ }) {
+ Some(problem) => unsafe { CStr::from_ptr(problem) },
None => CStr::from_bytes_with_nul(b"libyaml parser failed but there is no error\0"),
},
- problem_offset: (*parser).problem_offset,
+ problem_offset: unsafe { (*parser).problem_offset },
problem_mark: Mark {
- sys: (*parser).problem_mark,
+ sys: unsafe { (*parser).problem_mark },
},
- context: match NonNull::new((*parser).context as *mut _) {
- Some(context) => Some(CStr::from_ptr(context)),
+ context: match NonNull::new(unsafe { (*parser).context as *mut _ }) {
+ Some(context) => Some(unsafe { CStr::from_ptr(context) }),
None => None,
},
context_mark: Mark {
- sys: (*parser).context_mark,
+ sys: unsafe { (*parser).context_mark },
},
}
}
pub unsafe fn emit_error(emitter: *const sys::yaml_emitter_t) -> Self {
Error {
- kind: (*emitter).error,
- problem: match NonNull::new((*emitter).problem as *mut _) {
- Some(problem) => CStr::from_ptr(problem),
+ kind: unsafe { (*emitter).error },
+ problem: match NonNull::new(unsafe { (*emitter).problem as *mut _ }) {
+ Some(problem) => unsafe { CStr::from_ptr(problem) },
None => {
CStr::from_bytes_with_nul(b"libyaml emitter failed but there is no error\0")
}
},
problem_offset: 0,
problem_mark: Mark {
- sys: MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init(),
+ sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
context: None,
context_mark: Mark {
- sys: MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init(),
+ sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
}
}
diff --git a/src/libyaml/parser.rs b/src/libyaml/parser.rs
index ae8f375..3492edd 100644
--- a/src/libyaml/parser.rs
+++ b/src/libyaml/parser.rs
@@ -110,15 +110,16 @@ unsafe fn convert_event<'input>(
sys::YAML_STREAM_END_EVENT => Event::StreamEnd,
sys::YAML_DOCUMENT_START_EVENT => Event::DocumentStart,
sys::YAML_DOCUMENT_END_EVENT => Event::DocumentEnd,
- sys::YAML_ALIAS_EVENT => Event::Alias(optional_anchor(sys.data.alias.anchor).unwrap()),
+ sys::YAML_ALIAS_EVENT => {
+ Event::Alias(unsafe { optional_anchor(sys.data.alias.anchor) }.unwrap())
+ }
sys::YAML_SCALAR_EVENT => Event::Scalar(Scalar {
- anchor: optional_anchor(sys.data.scalar.anchor),
- tag: optional_tag(sys.data.scalar.tag),
- value: Box::from(slice::from_raw_parts(
- sys.data.scalar.value,
- sys.data.scalar.length as usize,
- )),
- style: match sys.data.scalar.style {
+ anchor: unsafe { optional_anchor(sys.data.scalar.anchor) },
+ tag: unsafe { optional_tag(sys.data.scalar.tag) },
+ value: Box::from(unsafe {
+ slice::from_raw_parts(sys.data.scalar.value, sys.data.scalar.length as usize)
+ }),
+ style: match unsafe { sys.data.scalar.style } {
sys::YAML_PLAIN_SCALAR_STYLE => ScalarStyle::Plain,
sys::YAML_SINGLE_QUOTED_SCALAR_STYLE => ScalarStyle::SingleQuoted,
sys::YAML_DOUBLE_QUOTED_SCALAR_STYLE => ScalarStyle::DoubleQuoted,
@@ -133,13 +134,13 @@ unsafe fn convert_event<'input>(
},
}),
sys::YAML_SEQUENCE_START_EVENT => Event::SequenceStart(SequenceStart {
- anchor: optional_anchor(sys.data.sequence_start.anchor),
- tag: optional_tag(sys.data.sequence_start.tag),
+ anchor: unsafe { optional_anchor(sys.data.sequence_start.anchor) },
+ tag: unsafe { optional_tag(sys.data.sequence_start.tag) },
}),
sys::YAML_SEQUENCE_END_EVENT => Event::SequenceEnd,
sys::YAML_MAPPING_START_EVENT => Event::MappingStart(MappingStart {
- anchor: optional_anchor(sys.data.mapping_start.anchor),
- tag: optional_tag(sys.data.mapping_start.tag),
+ anchor: unsafe { optional_anchor(sys.data.mapping_start.anchor) },
+ tag: unsafe { optional_tag(sys.data.mapping_start.tag) },
}),
sys::YAML_MAPPING_END_EVENT => Event::MappingEnd,
sys::YAML_NO_EVENT => unreachable!(),
@@ -149,13 +150,13 @@ unsafe fn convert_event<'input>(
unsafe fn optional_anchor(anchor: *const u8) -> Option<Anchor> {
let ptr = NonNull::new(anchor as *mut i8)?;
- let cstr = CStr::from_ptr(ptr);
+ let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Anchor(Box::from(cstr.to_bytes())))
}
unsafe fn optional_tag(tag: *const u8) -> Option<Tag> {
let ptr = NonNull::new(tag as *mut i8)?;
- let cstr = CStr::from_ptr(ptr);
+ let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Tag(Box::from(cstr.to_bytes())))
}
diff --git a/src/mapping.rs b/src/mapping.rs
index fe8d509..b1341a6 100644
--- a/src/mapping.rs
+++ b/src/mapping.rs
@@ -87,15 +87,65 @@ impl Mapping {
}
/// Removes and returns the value corresponding to the key from the map.
+ ///
+ /// This is equivalent to [`.swap_remove(index)`][Self::swap_remove],
+ /// replacing this entry’s position with the last element. If you need to
+ /// preserve the relative order of the keys in the map, use
+ /// [`.shift_remove(key)`][Self::shift_remove] instead.
#[inline]
pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> {
- index.remove_from(self)
+ self.swap_remove(index)
}
/// Remove and return the key-value pair.
+ ///
+ /// This is equivalent to [`.swap_remove_entry(index)`][Self::swap_remove_entry],
+ /// replacing this entry’s position with the last element. If you need to
+ /// preserve the relative order of the keys in the map, use
+ /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead.
#[inline]
pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
- index.remove_entry_from(self)
+ self.swap_remove_entry(index)
+ }
+
+ /// Removes and returns the value corresponding to the key from the map.
+ ///
+ /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
+ /// last element of the map and popping it off. This perturbs the position
+ /// of what used to be the last element!
+ #[inline]
+ pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
+ index.swap_remove_from(self)
+ }
+
+ /// Remove and return the key-value pair.
+ ///
+ /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
+ /// last element of the map and popping it off. This perturbs the position
+ /// of what used to be the last element!
+ #[inline]
+ pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
+ index.swap_remove_entry_from(self)
+ }
+
+ /// Removes and returns the value corresponding to the key from the map.
+ ///
+ /// Like [`Vec::remove`], the entry is removed by shifting all of the
+ /// elements that follow it, preserving their relative order. This perturbs
+ /// the index of all of those elements!
+ #[inline]
+ pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
+ index.shift_remove_from(self)
+ }
+
+ /// Remove and return the key-value pair.
+ ///
+ /// Like [`Vec::remove`], the entry is removed by shifting all of the
+ /// elements that follow it, preserving their relative order. This perturbs
+ /// the index of all of those elements!
+ #[inline]
+ pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
+ index.shift_remove_entry_from(self)
}
/// Scan through each key-value pair in the map and keep those where the
@@ -203,10 +253,16 @@ pub trait Index: private::Sealed {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
#[doc(hidden)]
- fn remove_from(&self, v: &mut Mapping) -> Option<Value>;
+ fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
+
+ #[doc(hidden)]
+ fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
+
+ #[doc(hidden)]
+ fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
#[doc(hidden)]
- fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
+ fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
}
struct HashLikeValue<'a>(&'a str);
@@ -239,11 +295,17 @@ impl Index for Value {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(self)
}
- fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
- v.map.remove(self)
+ fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ v.map.swap_remove(self)
}
- fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
- v.map.remove_entry(self)
+ fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ v.map.swap_remove_entry(self)
+ }
+ fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ v.map.shift_remove(self)
+ }
+ fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ v.map.shift_remove_entry(self)
}
}
@@ -257,11 +319,17 @@ impl Index for str {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
v.map.get_mut(&HashLikeValue(self))
}
- fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
- v.map.remove(&HashLikeValue(self))
+ fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ v.map.swap_remove(&HashLikeValue(self))
+ }
+ fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ v.map.swap_remove_entry(&HashLikeValue(self))
+ }
+ fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ v.map.shift_remove(&HashLikeValue(self))
}
- fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
- v.map.remove_entry(&HashLikeValue(self))
+ fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ v.map.shift_remove_entry(&HashLikeValue(self))
}
}
@@ -275,11 +343,17 @@ impl Index for String {
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
self.as_str().index_into_mut(v)
}
- fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
- self.as_str().remove_from(v)
+ fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ self.as_str().swap_remove_from(v)
}
- fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
- self.as_str().remove_entry_from(v)
+ fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ self.as_str().swap_remove_entry_from(v)
+ }
+ fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ self.as_str().shift_remove_from(v)
+ }
+ fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ self.as_str().shift_remove_entry_from(v)
}
}
@@ -296,11 +370,17 @@ where
fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
(**self).index_into_mut(v)
}
- fn remove_from(&self, v: &mut Mapping) -> Option<Value> {
- (**self).remove_from(v)
+ fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ (**self).swap_remove_from(v)
+ }
+ fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ (**self).swap_remove_entry_from(v)
+ }
+ fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
+ (**self).shift_remove_from(v)
}
- fn remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
- (**self).remove_entry_from(v)
+ fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
+ (**self).shift_remove_entry_from(v)
}
}
diff --git a/src/number.rs b/src/number.rs
index 3b0293b..5ebe395 100644
--- a/src/number.rs
+++ b/src/number.rs
@@ -517,22 +517,24 @@ macro_rules! from_unsigned {
};
}
-macro_rules! from_float {
- ($($float_ty:ident)*) => {
- $(
- impl From<$float_ty> for Number {
- #[inline]
- fn from(f: $float_ty) -> Self {
- Number { n: N::Float(f as f64) }
- }
- }
- )*
+from_signed!(i8 i16 i32 i64 isize);
+from_unsigned!(u8 u16 u32 u64 usize);
+
+impl From<f32> for Number {
+ fn from(f: f32) -> Self {
+ Number::from(f as f64)
}
}
-from_signed!(i8 i16 i32 i64 isize);
-from_unsigned!(u8 u16 u32 u64 usize);
-from_float!(f32 f64);
+impl From<f64> for Number {
+ fn from(mut f: f64) -> Self {
+ if f.is_nan() {
+ // Destroy NaN sign, signaling, and payload. YAML only has one NaN.
+ f = f64::NAN.copysign(1.0);
+ }
+ Number { n: N::Float(f) }
+ }
+}
// This is fine, because we don't _really_ implement hash for floats
// all other hash functions should work as expected
diff --git a/tests/test_de.rs b/tests/test_de.rs
index 840188f..b9e948d 100644
--- a/tests/test_de.rs
+++ b/tests/test_de.rs
@@ -451,6 +451,17 @@ fn test_numbers() {
}
#[test]
+fn test_nan() {
+ // There is no negative NaN in YAML.
+ assert!(serde_yaml::from_str::<f32>(".nan")
+ .unwrap()
+ .is_sign_positive());
+ assert!(serde_yaml::from_str::<f64>(".nan")
+ .unwrap()
+ .is_sign_positive());
+}
+
+#[test]
fn test_stateful() {
struct Seed(i64);
@@ -690,6 +701,7 @@ fn test_parse_number() {
let n = ".nan".parse::<Number>().unwrap();
assert_eq!(n, Number::from(f64::NAN));
+ assert!(n.as_f64().unwrap().is_sign_positive());
let n = ".inf".parse::<Number>().unwrap();
assert_eq!(n, Number::from(f64::INFINITY));
diff --git a/tests/test_error.rs b/tests/test_error.rs
index 65cec98..6439bd4 100644
--- a/tests/test_error.rs
+++ b/tests/test_error.rs
@@ -49,18 +49,16 @@ fn test_incorrect_type() {
#[test]
fn test_incorrect_nested_type() {
#[derive(Deserialize, Debug)]
- struct A {
- #[allow(dead_code)]
- b: Vec<B>,
+ pub struct A {
+ pub b: Vec<B>,
}
#[derive(Deserialize, Debug)]
- enum B {
+ pub enum B {
C(C),
}
#[derive(Deserialize, Debug)]
- struct C {
- #[allow(dead_code)]
- d: bool,
+ pub struct C {
+ pub d: bool,
}
let yaml = indoc! {"
b:
@@ -80,11 +78,9 @@ fn test_empty() {
#[test]
fn test_missing_field() {
#[derive(Deserialize, Debug)]
- struct Basic {
- #[allow(dead_code)]
- v: bool,
- #[allow(dead_code)]
- w: bool,
+ pub struct Basic {
+ pub v: bool,
+ pub w: bool,
}
let yaml = indoc! {"
---
@@ -107,9 +103,8 @@ fn test_unknown_anchor() {
#[test]
fn test_ignored_unknown_anchor() {
#[derive(Deserialize, Debug)]
- struct Wrapper {
- #[allow(dead_code)]
- c: (),
+ pub struct Wrapper {
+ pub c: (),
}
let yaml = indoc! {"
b: [*a]
@@ -161,7 +156,7 @@ fn test_second_document_syntax_error() {
#[test]
fn test_missing_enum_tag() {
#[derive(Deserialize, Debug)]
- enum E {
+ pub enum E {
V(usize),
}
let yaml = indoc! {r#"
@@ -175,11 +170,11 @@ fn test_missing_enum_tag() {
#[test]
fn test_serialize_nested_enum() {
#[derive(Serialize, Debug)]
- enum Outer {
+ pub enum Outer {
Inner(Inner),
}
#[derive(Serialize, Debug)]
- enum Inner {
+ pub enum Inner {
Newtype(usize),
Tuple(usize, usize),
Struct { x: usize },
@@ -213,11 +208,11 @@ fn test_serialize_nested_enum() {
#[test]
fn test_deserialize_nested_enum() {
#[derive(Deserialize, Debug)]
- enum Outer {
+ pub enum Outer {
Inner(Inner),
}
#[derive(Deserialize, Debug)]
- enum Inner {
+ pub enum Inner {
Variant(Vec<usize>),
}
@@ -246,25 +241,24 @@ fn test_deserialize_nested_enum() {
#[test]
fn test_variant_not_a_seq() {
#[derive(Deserialize, Debug)]
- enum E {
+ pub enum E {
V(usize),
}
- let yaml = indoc! {r#"
+ let yaml = indoc! {"
---
!V
value: 0
- "#};
+ "};
let expected = "invalid type: map, expected usize at line 2 column 1";
test_error::<E>(yaml, expected);
}
#[test]
fn test_struct_from_sequence() {
- #[allow(dead_code)]
#[derive(Deserialize, Debug)]
- struct Struct {
- x: usize,
- y: usize,
+ pub struct Struct {
+ pub x: usize,
+ pub y: usize,
}
let yaml = indoc! {"
[0, 0]
@@ -336,9 +330,8 @@ fn test_long_tuple() {
#[test]
fn test_invalid_scalar_type() {
#[derive(Deserialize, Debug)]
- struct S {
- #[allow(dead_code)]
- x: [i32; 1],
+ pub struct S {
+ pub x: [i32; 1],
}
let yaml = "x: ''\n";
@@ -350,9 +343,8 @@ fn test_invalid_scalar_type() {
#[test]
fn test_infinite_recursion_objects() {
#[derive(Deserialize, Debug)]
- struct S {
- #[allow(dead_code)]
- x: Option<Box<S>>,
+ pub struct S {
+ pub x: Option<Box<S>>,
}
let yaml = "&a {'x': *a}";
@@ -364,7 +356,7 @@ fn test_infinite_recursion_objects() {
#[test]
fn test_infinite_recursion_arrays() {
#[derive(Deserialize, Debug)]
- struct S(usize, Option<Box<S>>);
+ pub struct S(pub usize, pub Option<Box<S>>);
let yaml = "&a [0, *a]";
let expected = "recursion limit exceeded";
@@ -375,7 +367,7 @@ fn test_infinite_recursion_arrays() {
#[test]
fn test_infinite_recursion_newtype() {
#[derive(Deserialize, Debug)]
- struct S(Option<Box<S>>);
+ pub struct S(pub Option<Box<S>>);
let yaml = "&a [*a]";
let expected = "recursion limit exceeded";
@@ -386,9 +378,8 @@ fn test_infinite_recursion_newtype() {
#[test]
fn test_finite_recursion_objects() {
#[derive(Deserialize, Debug)]
- struct S {
- #[allow(dead_code)]
- x: Option<Box<S>>,
+ pub struct S {
+ pub x: Option<Box<S>>,
}
let yaml = "{'x':".repeat(1_000) + &"}".repeat(1_000);
@@ -400,7 +391,7 @@ fn test_finite_recursion_objects() {
#[test]
fn test_finite_recursion_arrays() {
#[derive(Deserialize, Debug)]
- struct S(usize, Option<Box<S>>);
+ pub struct S(pub usize, pub Option<Box<S>>);
let yaml = "[0, ".repeat(1_000) + &"]".repeat(1_000);
let expected = "recursion limit exceeded at line 1 column 513";
diff --git a/tests/test_serde.rs b/tests/test_serde.rs
index d332df4..f16e89c 100644
--- a/tests/test_serde.rs
+++ b/tests/test_serde.rs
@@ -246,9 +246,9 @@ fn test_basic_struct() {
#[test]
fn test_string_escapes() {
- let yaml = indoc! {r#"
+ let yaml = indoc! {"
ascii
- "#};
+ "};
test_serde(&"ascii".to_owned(), yaml);
let yaml = indoc! {r#"
@@ -264,9 +264,9 @@ fn test_string_escapes() {
"#};
test_serde(&"\u{1f}\u{feff}".to_owned(), yaml);
- let yaml = indoc! {r#"
+ let yaml = indoc! {"
🎉
- "#};
+ "};
test_serde(&"\u{1f389}".to_owned(), yaml);
}
@@ -281,14 +281,14 @@ fn test_multiline_string() {
trailing_newline: "aaa\nbbb\n".to_owned(),
no_trailing_newline: "aaa\nbbb".to_owned(),
};
- let yaml = indoc! {r#"
+ let yaml = indoc! {"
trailing_newline: |
aaa
bbb
no_trailing_newline: |-
aaa
bbb
- "#};
+ "};
test_serde(&thing, yaml);
}
@@ -307,12 +307,12 @@ fn test_strings_needing_quote() {
void: "null".to_owned(),
leading_zeros: "007".to_owned(),
};
- let yaml = indoc! {r#"
+ let yaml = indoc! {"
boolean: 'true'
integer: '1'
void: 'null'
leading_zeros: '007'
- "#};
+ "};
test_serde(&thing, yaml);
}
diff --git a/tests/test_value.rs b/tests/test_value.rs
index a7dd448..cce8329 100644
--- a/tests/test_value.rs
+++ b/tests/test_value.rs
@@ -20,7 +20,7 @@ fn test_nan() {
assert!(neg_fake_nan.is_string());
let significand_mask = 0xF_FFFF_FFFF_FFFF;
- let bits = (f64::NAN.to_bits() ^ significand_mask) | 1;
+ let bits = (f64::NAN.copysign(1.0).to_bits() ^ significand_mask) | 1;
let different_pos_nan = Value::Number(Number::from(f64::from_bits(bits)));
assert_eq!(pos_nan, different_pos_nan);
}