aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--.github/workflows/ci.yml63
-rw-r--r--Android.bp4
-rw-r--r--Cargo.toml28
-rw-r--r--Cargo.toml.orig23
-rw-r--r--LICENSE-APACHE25
-rw-r--r--METADATA14
-rw-r--r--README.md120
-rw-r--r--TEST_MAPPING23
-rw-r--r--build.rs2
-rw-r--r--src/de.rs154
-rw-r--r--src/error.rs12
-rw-r--r--src/lib.rs33
-rw-r--r--src/map.rs26
-rw-r--r--src/number.rs73
-rw-r--r--src/raw.rs2
-rw-r--r--src/read.rs6
-rw-r--r--src/ser.rs406
-rw-r--r--src/value/de.rs87
-rw-r--r--src/value/from.rs21
-rw-r--r--src/value/index.rs26
-rw-r--r--src/value/mod.rs76
-rw-r--r--src/value/ser.rs86
-rw-r--r--tests/debug.rs43
-rw-r--r--tests/macros/mod.rs2
-rw-r--r--tests/regression/issue795.rs2
-rw-r--r--tests/regression/issue845.rs2
-rw-r--r--tests/regression/issue953.rs9
-rw-r--r--tests/stream.rs1
-rw-r--r--tests/test.rs32
-rw-r--r--tests/ui/missing_colon.stderr7
-rw-r--r--tests/ui/missing_comma.stderr6
-rw-r--r--tests/ui/missing_value.stderr7
-rw-r--r--tests/ui/parse_expr.stderr6
-rw-r--r--tests/ui/unexpected_after_array_element.stderr2
-rw-r--r--tests/ui/unexpected_after_map_entry.stderr2
-rw-r--r--tests/ui/unexpected_colon.stderr2
-rw-r--r--tests/ui/unexpected_comma.stderr2
38 files changed, 705 insertions, 732 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 55d7152..3fa35ed 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "7025523603fe604d11b92ccd4ca314e343d3ae50"
+ "sha1": "0ebeede28a0d5f0f07f18124078f55d62b180a2d"
},
"path_in_vcs": ""
} \ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b7e82ab..bfaffaf 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,6 +5,9 @@ on:
pull_request:
schedule: [cron: "40 1 * * *"]
+permissions:
+ contents: read
+
env:
RUSTFLAGS: -Dwarnings
@@ -16,8 +19,9 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu, windows]
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cargo test
- run: cargo test --features preserve_order --tests -- --skip ui --exact
@@ -33,47 +37,46 @@ jobs:
strategy:
fail-fast: false
matrix:
- rust: [beta, stable, 1.53.0, 1.46.0, 1.45.0, 1.40.0, 1.38.0, 1.36.0]
+ rust: [beta, 1.56.1, 1.53.0, 1.46.0, 1.40.0, 1.38.0, 1.36.0]
os: [ubuntu]
include:
- rust: stable
+ os: ubuntu
+ target: aarch64-unknown-none
+ - rust: stable
os: windows
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
+ targets: ${{matrix.target}}
- run: cargo check
- run: cargo check --features float_roundtrip
- run: cargo check --features arbitrary_precision
- run: cargo check --features raw_value
- run: cargo check --features unbounded_depth
- run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc
+ - run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,arbitrary_precision
- run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,raw_value
- run: cargo check --features preserve_order
- if: matrix.rust != '1.45.0' && matrix.rust != '1.40.0' && matrix.rust != '1.38.0' && matrix.rust != '1.36.0'
+ if: matrix.rust != '1.53.0' && matrix.rust != '1.46.0' && matrix.rust != '1.45.0' && matrix.rust != '1.40.0' && matrix.rust != '1.38.0' && matrix.rust != '1.36.0'
- run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,preserve_order
- if: matrix.rust != '1.45.0' && matrix.rust != '1.40.0' && matrix.rust != '1.38.0' && matrix.rust != '1.36.0'
+ if: matrix.rust != '1.53.0' && matrix.rust != '1.46.0' && matrix.rust != '1.45.0' && matrix.rust != '1.40.0' && matrix.rust != '1.38.0' && matrix.rust != '1.36.0'
- name: Build without std
- run: |
- rustup target add aarch64-unknown-none
- cargo check \
- --manifest-path tests/crate/Cargo.toml \
- --target aarch64-unknown-none \
- --no-default-features \
- --features alloc
- if: matrix.rust == 'stable' && matrix.os == 'ubuntu'
+ run: cargo check --manifest-path tests/crate/Cargo.toml --target ${{matrix.target}} --no-default-features --features alloc
+ if: matrix.target
miri:
name: Miri
runs-on: ubuntu-latest
env:
- MIRIFLAGS: "-Zmiri-tag-raw-pointers"
+ MIRIFLAGS: -Zmiri-strict-provenance
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
- - uses: dtolnay/rust-toolchain@nightly
- with:
- components: miri
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@miri
- run: cargo miri test
- run: cargo miri test --features preserve_order,float_roundtrip,arbitrary_precision,raw_value
@@ -81,8 +84,9 @@ jobs:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@clippy
- run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
- run: cargo clippy --all-features --tests -- -Dclippy::all -Dclippy::pedantic
@@ -90,8 +94,9 @@ jobs:
docs:
name: Documentation
runs-on: ubuntu-latest
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cargo doc --features raw_value,unbounded_depth
env:
@@ -100,8 +105,20 @@ jobs:
fuzz:
name: Fuzz
runs-on: ubuntu-latest
+ timeout-minutes: 45
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- - run: cargo install cargo-fuzz --debug
- - run: cargo fuzz build -O
+ - uses: dtolnay/install@cargo-fuzz
+ - run: cargo fuzz check
+
+ outdated:
+ name: Outdated
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - 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 4768c80..c10af9a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@ rust_library {
host_supported: true,
crate_name: "serde_json",
cargo_env_compat: true,
- cargo_pkg_version: "1.0.79",
+ cargo_pkg_version: "1.0.93",
srcs: ["src/lib.rs"],
edition: "2018",
features: [
@@ -60,4 +60,6 @@ rust_library {
"//apex_available:platform",
"com.android.virt",
],
+ product_available: true,
+ vendor_available: true,
}
diff --git a/Cargo.toml b/Cargo.toml
index cf800d8..cff28cd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,20 +13,24 @@
edition = "2018"
rust-version = "1.36"
name = "serde_json"
-version = "1.0.79"
+version = "1.0.93"
authors = [
"Erick Tryzelaar <erick.tryzelaar@gmail.com>",
"David Tolnay <dtolnay@gmail.com>",
]
description = "A JSON serialization file format"
-documentation = "https://docs.serde.rs/serde_json/"
+documentation = "https://docs.rs/serde_json"
readme = "README.md"
keywords = [
"json",
"serde",
"serialization",
]
-categories = ["encoding"]
+categories = [
+ "encoding",
+ "parser-implementations",
+ "no-std",
+]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/json"
@@ -44,8 +48,12 @@ rustdoc-args = [
[package.metadata.playground]
features = ["raw_value"]
+[lib]
+doc-scrape-examples = false
+
[dependencies.indexmap]
-version = "1.5"
+version = "1.5.2"
+features = ["std"]
optional = true
[dependencies.itoa]
@@ -61,12 +69,19 @@ default-features = false
[dev-dependencies.automod]
version = "1.0"
+[dev-dependencies.indoc]
+version = "2.0"
+
[dev-dependencies.ref-cast]
version = "1.0"
[dev-dependencies.rustversion]
version = "1.0"
+[dev-dependencies.serde]
+version = "1.0.100"
+features = ["derive"]
+
[dev-dependencies.serde_bytes]
version = "0.11"
@@ -85,7 +100,10 @@ alloc = ["serde/alloc"]
arbitrary_precision = []
default = ["std"]
float_roundtrip = []
-preserve_order = ["indexmap"]
+preserve_order = [
+ "indexmap",
+ "std",
+]
raw_value = []
std = ["serde/std"]
unbounded_depth = []
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 1513e9b..3e8fa0d 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,27 +1,28 @@
[package]
name = "serde_json"
-version = "1.0.79" # remember to update html_root_url
+version = "1.0.93" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-license = "MIT OR Apache-2.0"
+categories = ["encoding", "parser-implementations", "no-std"]
description = "A JSON serialization file format"
-repository = "https://github.com/serde-rs/json"
-documentation = "https://docs.serde.rs/serde_json/"
-keywords = ["json", "serde", "serialization"]
-categories = ["encoding"]
-readme = "README.md"
+documentation = "https://docs.rs/serde_json"
edition = "2018"
+keywords = ["json", "serde", "serialization"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/serde-rs/json"
rust-version = "1.36"
[dependencies]
serde = { version = "1.0.100", default-features = false }
-indexmap = { version = "1.5", optional = true }
+indexmap = { version = "1.5.2", features = ["std"], optional = true }
itoa = "1.0"
ryu = "1.0"
[dev-dependencies]
automod = "1.0"
+indoc = "2.0"
ref-cast = "1.0"
rustversion = "1.0"
+serde = { version = "1.0.100", features = ["derive"] }
serde_bytes = "0.11"
serde_derive = "1.0"
serde_stacker = "0.1"
@@ -30,6 +31,9 @@ trybuild = { version = "1.0.49", features = ["diff"] }
[workspace]
members = ["tests/crate"]
+[lib]
+doc-scrape-examples = false
+
[package.metadata.docs.rs]
features = ["raw_value", "unbounded_depth"]
targets = ["x86_64-unknown-linux-gnu"]
@@ -49,13 +53,12 @@ std = ["serde/std"]
# Provide integration for heap-allocated collections without depending on the
# rest of the Rust standard library.
# NOTE: Disabling both `std` *and* `alloc` features is not supported yet.
-# Available on Rust 1.36+.
alloc = ["serde/alloc"]
# Make serde_json::Map use a representation which maintains insertion order.
# This allows data to be read into a Value and written back to a JSON string
# while preserving the order of map keys in the input.
-preserve_order = ["indexmap"]
+preserve_order = ["indexmap", "std"]
# Use sufficient precision when parsing fixed precision floats from JSON to
# ensure that they maintain accuracy when round-tripped through JSON. This comes
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 16fe87b..1b5ec8b 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
diff --git a/METADATA b/METADATA
index b5c0cc6..6040edb 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,7 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update rust/crates/serde_json
+# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+
name: "serde_json"
description: "A JSON serialization file format"
third_party {
@@ -7,13 +11,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/serde_json/serde_json-1.0.79.crate"
+ value: "https://static.crates.io/crates/serde_json/serde_json-1.0.93.crate"
}
- version: "1.0.79"
+ version: "1.0.93"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 3
- day: 1
+ year: 2023
+ month: 2
+ day: 17
}
}
diff --git a/README.md b/README.md
index 6d8af69..d704979 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
-# Serde JSON &emsp; [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc]
+# Serde JSON &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc]
-[Build Status]: https://img.shields.io/github/workflow/status/serde-rs/json/CI/master
-[travis]: https://github.com/serde-rs/json/actions?query=branch%3Amaster
+[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master
+[actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster
[Latest Version]: https://img.shields.io/crates/v/serde_json.svg
[crates.io]: https://crates.io/crates/serde\_json
[Rustc Version 1.36+]: https://img.shields.io/badge/rustc-1.36+-lightgray.svg
@@ -18,8 +18,8 @@ serde_json = "1.0"
You may be looking for:
-- [JSON API documentation](https://docs.serde.rs/serde_json/)
-- [Serde API documentation](https://docs.serde.rs/serde/)
+- [JSON API documentation](https://docs.rs/serde_json)
+- [Serde API documentation](https://docs.rs/serde)
- [Detailed documentation about Serde](https://serde.rs/)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Release notes](https://github.com/serde-rs/json/releases)
@@ -42,22 +42,21 @@ transmit data objects consisting of key-value pairs.
}
```
-There are three common ways that you might find yourself needing to work
-with JSON data in Rust.
+There are three common ways that you might find yourself needing to work with
+JSON data in Rust.
- - **As text data.** An unprocessed string of JSON data that you receive on
- an HTTP endpoint, read from a file, or prepare to send to a remote
- server.
- - **As an untyped or loosely typed representation.** Maybe you want to
- check that some JSON data is valid before passing it on, but without
- knowing the structure of what it contains. Or you want to do very basic
- manipulations like insert a key in a particular spot.
- - **As a strongly typed Rust data structure.** When you expect all or most
- of your data to conform to a particular structure and want to get real
- work done without JSON's loosey-goosey nature tripping you up.
+ - **As text data.** An unprocessed string of JSON data that you receive on an
+ HTTP endpoint, read from a file, or prepare to send to a remote server.
+ - **As an untyped or loosely typed representation.** Maybe you want to check
+ that some JSON data is valid before passing it on, but without knowing the
+ structure of what it contains. Or you want to do very basic manipulations
+ like insert a key in a particular spot.
+ - **As a strongly typed Rust data structure.** When you expect all or most of
+ your data to conform to a particular structure and want to get real work done
+ without JSON's loosey-goosey nature tripping you up.
-Serde JSON provides efficient, flexible, safe ways of converting data
-between each of these representations.
+Serde JSON provides efficient, flexible, safe ways of converting data between
+each of these representations.
## Operating on untyped JSON values
@@ -78,8 +77,8 @@ enum Value {
A string of JSON data can be parsed into a `serde_json::Value` by the
[`serde_json::from_str`][from_str] function. There is also
[`from_slice`][from_slice] for parsing from a byte slice &[u8] and
-[`from_reader`][from_reader] for parsing from any `io::Read` like a File or
-a TCP stream.
+[`from_reader`][from_reader] for parsing from any `io::Read` like a File or a
+TCP stream.
<div align="right">
<a href="https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72" target="_blank">
@@ -127,7 +126,7 @@ without quotation marks involves converting from a JSON string to a Rust string
with [`as_str()`] or avoiding the use of `Value` as described in the following
section.
-[`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str
+[`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str
The `Value` representation is sufficient for very basic tasks but can be tedious
to work with for anything more significant. Error handling is verbose to
@@ -185,20 +184,20 @@ fn typed_example() -> Result<()> {
This is the same `serde_json::from_str` function as before, but this time we
assign the return value to a variable of type `Person` so Serde will
automatically interpret the input data as a `Person` and produce informative
-error messages if the layout does not conform to what a `Person` is expected
-to look like.
+error messages if the layout does not conform to what a `Person` is expected to
+look like.
-Any type that implements Serde's `Deserialize` trait can be deserialized
-this way. This includes built-in Rust standard library types like `Vec<T>`
-and `HashMap<K, V>`, as well as any structs or enums annotated with
+Any type that implements Serde's `Deserialize` trait can be deserialized this
+way. This includes built-in Rust standard library types like `Vec<T>` and
+`HashMap<K, V>`, as well as any structs or enums annotated with
`#[derive(Deserialize)]`.
-Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
-use it correctly like they do for any other Rust code. The IDE can
-autocomplete field names to prevent typos, which was impossible in the
-`serde_json::Value` representation. And the Rust compiler can check that
-when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
-`Vec<String>` so indexing into it makes sense and produces a `String`.
+Once we have `p` of type `Person`, our IDE and the Rust compiler can help us use
+it correctly like they do for any other Rust code. The IDE can autocomplete
+field names to prevent typos, which was impossible in the `serde_json::Value`
+representation. And the Rust compiler can check that when we write
+`p.phones[0]`, then `p.phones` is guaranteed to be a `Vec<String>` so indexing
+into it makes sense and produces a `String`.
The necessary setup for using Serde's derive macros is explained on the *[Using
derive]* page of the Serde site.
@@ -237,13 +236,13 @@ fn main() {
}
```
-The `Value::to_string()` function converts a `serde_json::Value` into a
-`String` of JSON text.
+The `Value::to_string()` function converts a `serde_json::Value` into a `String`
+of JSON text.
-One neat thing about the `json!` macro is that variables and expressions can
-be interpolated directly into the JSON value as you are building it. Serde
-will check at compile time that the value you are interpolating is able to
-be represented as JSON.
+One neat thing about the `json!` macro is that variables and expressions can be
+interpolated directly into the JSON value as you are building it. Serde will
+check at compile time that the value you are interpolating is able to be
+represented as JSON.
<div align="right">
<a href="https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2" target="_blank">
@@ -265,10 +264,10 @@ let john = json!({
});
```
-This is amazingly convenient but we have the problem we had before with
-`Value` which is that the IDE and Rust compiler cannot help us if we get it
-wrong. Serde JSON provides a better way of serializing strongly-typed data
-structures into JSON text.
+This is amazingly convenient, but we have the problem we had before with
+`Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON
+provides a better way of serializing strongly-typed data structures into JSON
+text.
## Creating JSON by serializing data structures
@@ -311,10 +310,9 @@ fn print_an_address() -> Result<()> {
}
```
-Any type that implements Serde's `Serialize` trait can be serialized this
-way. This includes built-in Rust standard library types like `Vec<T>` and
-`HashMap<K, V>`, as well as any structs or enums annotated with
-`#[derive(Serialize)]`.
+Any type that implements Serde's `Serialize` trait can be serialized this way.
+This includes built-in Rust standard library types like `Vec<T>` and `HashMap<K,
+V>`, as well as any structs or enums annotated with `#[derive(Serialize)]`.
## Performance
@@ -328,16 +326,16 @@ Benchmarks live in the [serde-rs/json-benchmark] repo.
## Getting help
-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
-[#rust-questions] or [#rust-beginners] channels of the unofficial community
+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 [#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
+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
@@ -352,8 +350,8 @@ closed without a response after some time.
## No-std support
As long as there is a memory allocator, it is possible to use serde_json without
-the rest of the Rust standard library. This is supported on Rust 1.36+. Disable
-the default "std" feature and enable the "alloc" feature:
+the rest of the Rust standard library. Disable the default "std" feature and
+enable the "alloc" feature:
```toml
[dependencies]
@@ -365,14 +363,14 @@ For JSON support in Serde without a memory allocator, please see the
[`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
-[value]: https://docs.serde.rs/serde_json/value/enum.Value.html
-[from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
-[from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
-[from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
-[to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
-[to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
-[to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html
-[macro]: https://docs.serde.rs/serde_json/macro.json.html
+[value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html
+[from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html
+[from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html
+[from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html
+[to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html
+[to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html
+[to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html
+[macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html
<br>
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 42777bd..872a238 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -24,34 +24,21 @@
},
{
"path": "external/rust/crates/url"
- }
- ],
- "presubmit": [
- {
- "name": "ZipFuseTest"
- },
- {
- "name": "authfs_device_test_src_lib"
},
{
- "name": "microdroid_manager_test"
+ "path": "packages/modules/Virtualization/authfs"
},
{
- "name": "virtualizationservice_device_test"
- }
- ],
- "presubmit-rust": [
- {
- "name": "ZipFuseTest"
+ "path": "packages/modules/Virtualization/microdroid_manager"
},
{
- "name": "authfs_device_test_src_lib"
+ "path": "packages/modules/Virtualization/virtualizationmanager"
},
{
- "name": "microdroid_manager_test"
+ "path": "packages/modules/Virtualization/vm"
},
{
- "name": "virtualizationservice_device_test"
+ "path": "packages/modules/Virtualization/zipfuse"
}
]
}
diff --git a/build.rs b/build.rs
index e9ec7d5..0e12602 100644
--- a/build.rs
+++ b/build.rs
@@ -3,6 +3,8 @@ use std::process::Command;
use std::str::{self, FromStr};
fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+
// Decide ideal limb width for arithmetic in the float parser. Refer to
// src/lexical/math.rs for where this has an effect.
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
diff --git a/src/de.rs b/src/de.rs
index ffd0d48..88d0f26 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -14,7 +14,7 @@ use core::marker::PhantomData;
use core::result;
use core::str::FromStr;
use serde::de::{self, Expected, Unexpected};
-use serde::{forward_to_deserialize_any, serde_if_integer128};
+use serde::forward_to_deserialize_any;
#[cfg(feature = "arbitrary_precision")]
use crate::number::NumberDeserializer;
@@ -335,31 +335,25 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}
}
- serde_if_integer128! {
- fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
- match tri!(self.next_char_or_null()) {
- b'0' => {
- buf.push('0');
- // There can be only one leading '0'.
- match tri!(self.peek_or_null()) {
- b'0'..=b'9' => {
- Err(self.peek_error(ErrorCode::InvalidNumber))
- }
- _ => Ok(()),
- }
+ fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
+ match tri!(self.next_char_or_null()) {
+ b'0' => {
+ buf.push('0');
+ // There can be only one leading '0'.
+ match tri!(self.peek_or_null()) {
+ b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ _ => Ok(()),
}
- c @ b'1'..=b'9' => {
+ }
+ c @ b'1'..=b'9' => {
+ buf.push(c as char);
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
buf.push(c as char);
- while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
- self.eat_char();
- buf.push(c as char);
- }
- Ok(())
- }
- _ => {
- Err(self.error(ErrorCode::InvalidNumber))
}
+ Ok(())
}
+ _ => Err(self.error(ErrorCode::InvalidNumber)),
}
}
@@ -457,30 +451,33 @@ impl<'de, R: Read<'de>> Deserializer<R> {
&mut self,
positive: bool,
mut significand: u64,
- mut exponent: i32,
+ exponent_before_decimal_point: i32,
) -> Result<f64> {
self.eat_char();
+ let mut exponent_after_decimal_point = 0;
while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
let digit = (c - b'0') as u64;
if overflow!(significand * 10 + digit, u64::max_value()) {
+ let exponent = exponent_before_decimal_point + exponent_after_decimal_point;
return self.parse_decimal_overflow(positive, significand, exponent);
}
self.eat_char();
significand = significand * 10 + digit;
- exponent -= 1;
+ exponent_after_decimal_point -= 1;
}
// Error if there is not at least one digit after the decimal point.
- if exponent == 0 {
+ if exponent_after_decimal_point == 0 {
match tri!(self.peek()) {
Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
}
}
+ let exponent = exponent_before_decimal_point + exponent_after_decimal_point;
match tri!(self.peek_or_null()) {
b'e' | b'E' => self.parse_exponent(positive, significand, exponent),
_ => self.f64_from_parts(positive, significand, exponent),
@@ -1437,67 +1434,65 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
val
}
- serde_if_integer128! {
- fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
- where
- V: de::Visitor<'de>,
- {
- let mut buf = String::new();
-
- match tri!(self.parse_whitespace()) {
- Some(b'-') => {
- self.eat_char();
- buf.push('-');
- }
- Some(_) => {}
- None => {
- return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
- }
- };
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let mut buf = String::new();
- tri!(self.scan_integer128(&mut buf));
+ match tri!(self.parse_whitespace()) {
+ Some(b'-') => {
+ self.eat_char();
+ buf.push('-');
+ }
+ Some(_) => {}
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
- let value = match buf.parse() {
- Ok(int) => visitor.visit_i128(int),
- Err(_) => {
- return Err(self.error(ErrorCode::NumberOutOfRange));
- }
- };
+ tri!(self.scan_integer128(&mut buf));
- match value {
- Ok(value) => Ok(value),
- Err(err) => Err(self.fix_position(err)),
+ let value = match buf.parse() {
+ Ok(int) => visitor.visit_i128(int),
+ Err(_) => {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
}
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
}
+ }
- fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
- where
- V: de::Visitor<'de>,
- {
- match tri!(self.parse_whitespace()) {
- Some(b'-') => {
- return Err(self.peek_error(ErrorCode::NumberOutOfRange));
- }
- Some(_) => {}
- None => {
- return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
- }
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match tri!(self.parse_whitespace()) {
+ Some(b'-') => {
+ return Err(self.peek_error(ErrorCode::NumberOutOfRange));
}
+ Some(_) => {}
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ }
- let mut buf = String::new();
- tri!(self.scan_integer128(&mut buf));
-
- let value = match buf.parse() {
- Ok(int) => visitor.visit_u128(int),
- Err(_) => {
- return Err(self.error(ErrorCode::NumberOutOfRange));
- }
- };
+ let mut buf = String::new();
+ tri!(self.scan_integer128(&mut buf));
- match value {
- Ok(value) => Ok(value),
- Err(err) => Err(self.fix_position(err)),
+ let value = match buf.parse() {
+ Ok(int) => visitor.visit_u128(int),
+ Err(_) => {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
}
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
}
}
@@ -2164,15 +2159,12 @@ where
deserialize_integer_key!(deserialize_i16 => visit_i16);
deserialize_integer_key!(deserialize_i32 => visit_i32);
deserialize_integer_key!(deserialize_i64 => visit_i64);
+ deserialize_integer_key!(deserialize_i128 => visit_i128);
deserialize_integer_key!(deserialize_u8 => visit_u8);
deserialize_integer_key!(deserialize_u16 => visit_u16);
deserialize_integer_key!(deserialize_u32 => visit_u32);
deserialize_integer_key!(deserialize_u64 => visit_u64);
-
- serde_if_integer128! {
- deserialize_integer_key!(deserialize_i128 => visit_i128);
- deserialize_integer_key!(deserialize_u128 => visit_u128);
- }
+ deserialize_integer_key!(deserialize_u128 => visit_u128);
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
diff --git a/src/error.rs b/src/error.rs
index 6390c43..1875ef0 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -284,9 +284,9 @@ impl Error {
impl Display for ErrorCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- ErrorCode::Message(ref msg) => f.write_str(msg),
- ErrorCode::Io(ref err) => Display::fmt(err, f),
+ match self {
+ ErrorCode::Message(msg) => f.write_str(msg),
+ ErrorCode::Io(err) => Display::fmt(err, f),
ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"),
ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"),
ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"),
@@ -318,8 +318,8 @@ impl Display for ErrorCode {
impl serde::de::StdError for Error {
#[cfg(feature = "std")]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- match self.err.code {
- ErrorCode::Io(ref err) => Some(err),
+ match &self.err.code {
+ ErrorCode::Io(err) => Some(err),
_ => None,
}
}
@@ -438,7 +438,7 @@ fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> {
}
fn starts_with_digit(slice: &str) -> bool {
- match slice.as_bytes().get(0) {
+ match slice.as_bytes().first() {
None => false,
Some(&byte) => byte >= b'0' && byte <= b'9',
}
diff --git a/src/lib.rs b/src/lib.rs
index 63846e7..48d0fe2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -104,7 +104,7 @@
//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of
//! `Value` as described in the following section.
//!
-//! [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str
+//! [`as_str()`]: crate::Value::as_str
//!
//! The `Value` representation is sufficient for very basic tasks but can be
//! tedious to work with for anything more significant. Error handling is
@@ -227,10 +227,10 @@
//! });
//! ```
//!
-//! This is amazingly convenient but we have the problem we had before with
-//! `Value` which is that the IDE and Rust compiler cannot help us if we get it
-//! wrong. Serde JSON provides a better way of serializing strongly-typed data
-//! structures into JSON text.
+//! This is amazingly convenient, but we have the problem we had before with
+//! `Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde
+//! JSON provides a better way of serializing strongly-typed data structures
+//! into JSON text.
//!
//! # Creating JSON by serializing data structures
//!
@@ -279,8 +279,8 @@
//! # No-std support
//!
//! As long as there is a memory allocator, it is possible to use serde_json
-//! without the rest of the Rust standard library. This is supported on Rust
-//! 1.36+. Disable the default "std" feature and enable the "alloc" feature:
+//! without the rest of the Rust standard library. Disable the default "std"
+//! feature and enable the "alloc" feature:
//!
//! ```toml
//! [dependencies]
@@ -290,17 +290,17 @@
//! For JSON support in Serde without a memory allocator, please see the
//! [`serde-json-core`] crate.
//!
-//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html
-//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
-//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
-//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
-//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html
-//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html
-//! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html
-//! [macro]: https://docs.serde.rs/serde_json/macro.json.html
+//! [value]: crate::value::Value
+//! [from_str]: crate::de::from_str
+//! [from_slice]: crate::de::from_slice
+//! [from_reader]: crate::de::from_reader
+//! [to_string]: crate::ser::to_string
+//! [to_vec]: crate::ser::to_vec
+//! [to_writer]: crate::ser::to_writer
+//! [macro]: crate::json
//! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
-#![doc(html_root_url = "https://docs.rs/serde_json/1.0.79")]
+#![doc(html_root_url = "https://docs.rs/serde_json/1.0.93")]
// Ignored clippy lints
#![allow(
clippy::collapsible_else_if,
@@ -308,6 +308,7 @@
clippy::deprecated_cfg_attr,
clippy::doc_markdown,
clippy::excessive_precision,
+ clippy::explicit_auto_deref,
clippy::float_cmp,
clippy::manual_range_contains,
clippy::match_like_matches_macro,
diff --git a/src/map.rs b/src/map.rs
index 146eb6a..3e8a381 100644
--- a/src/map.rs
+++ b/src/map.rs
@@ -193,13 +193,12 @@ impl Map<String, Value> {
}
}
- /// Moves all elements from other into Self, leaving other empty.
+ /// Moves all elements from other into self, leaving other empty.
#[inline]
pub fn append(&mut self, other: &mut Self) {
#[cfg(feature = "preserve_order")]
- for (k, v) in mem::replace(&mut other.map, MapImpl::default()) {
- self.map.insert(k, v);
- }
+ self.map
+ .extend(mem::replace(&mut other.map, MapImpl::default()));
#[cfg(not(feature = "preserve_order"))]
self.map.append(&mut other.map);
}
@@ -304,6 +303,11 @@ impl Clone for Map<String, Value> {
map: self.map.clone(),
}
}
+
+ #[inline]
+ fn clone_from(&mut self, source: &Self) {
+ self.map.clone_from(&source.map);
+ }
}
impl PartialEq for Map<String, Value> {
@@ -323,10 +327,10 @@ impl Eq for Map<String, Value> {}
/// #
/// # let val = &Value::String("".to_owned());
/// # let _ =
-/// match *val {
-/// Value::String(ref s) => Some(s.as_str()),
-/// Value::Array(ref arr) => arr[0].as_str(),
-/// Value::Object(ref map) => map["type"].as_str(),
+/// match val {
+/// Value::String(s) => Some(s.as_str()),
+/// Value::Array(arr) => arr[0].as_str(),
+/// Value::Object(map) => map["type"].as_str(),
/// _ => None,
/// }
/// # ;
@@ -530,9 +534,9 @@ impl<'a> Entry<'a> {
/// assert_eq!(map.entry("serde").key(), &"serde");
/// ```
pub fn key(&self) -> &String {
- match *self {
- Entry::Vacant(ref e) => e.key(),
- Entry::Occupied(ref e) => e.key(),
+ match self {
+ Entry::Vacant(e) => e.key(),
+ Entry::Occupied(e) => e.key(),
}
}
diff --git a/src/number.rs b/src/number.rs
index b965271..21a7641 100644
--- a/src/number.rs
+++ b/src/number.rs
@@ -1,18 +1,18 @@
use crate::de::ParserNumber;
use crate::error::Error;
+#[cfg(feature = "arbitrary_precision")]
+use crate::error::ErrorCode;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::borrow::ToOwned;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::string::{String, ToString};
use core::fmt::{self, Debug, Display};
#[cfg(not(feature = "arbitrary_precision"))]
use core::hash::{Hash, Hasher};
use serde::de::{self, Unexpected, Visitor};
-use serde::{
- forward_to_deserialize_any, serde_if_integer128, Deserialize, Deserializer, Serialize,
- Serializer,
-};
-
-#[cfg(feature = "arbitrary_precision")]
-use crate::error::ErrorCode;
#[cfg(feature = "arbitrary_precision")]
use serde::de::{IntoDeserializer, MapAccess};
+use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "arbitrary_precision")]
pub(crate) const TOKEN: &str = "$serde_json::private::Number";
@@ -292,9 +292,9 @@ impl Display for Number {
#[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.n {
- N::PosInt(u) => Display::fmt(&u, formatter),
- N::NegInt(i) => Display::fmt(&i, formatter),
- N::Float(f) => Display::fmt(&f, formatter),
+ N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
+ N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
+ N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
}
}
@@ -305,29 +305,8 @@ impl Display for Number {
}
impl Debug for Number {
- #[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- let mut debug = formatter.debug_tuple("Number");
- match self.n {
- N::PosInt(i) => {
- debug.field(&i);
- }
- N::NegInt(i) => {
- debug.field(&i);
- }
- N::Float(f) => {
- debug.field(&f);
- }
- }
- debug.finish()
- }
-
- #[cfg(feature = "arbitrary_precision")]
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter
- .debug_tuple("Number")
- .field(&format_args!("{}", self.n))
- .finish()
+ write!(formatter, "Number({})", self)
}
}
@@ -558,18 +537,15 @@ impl<'de> Deserializer<'de> for Number {
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
+ deserialize_number!(deserialize_i128 => visit_i128);
deserialize_number!(deserialize_u8 => visit_u8);
deserialize_number!(deserialize_u16 => visit_u16);
deserialize_number!(deserialize_u32 => visit_u32);
deserialize_number!(deserialize_u64 => visit_u64);
+ deserialize_number!(deserialize_u128 => visit_u128);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);
- serde_if_integer128! {
- deserialize_number!(deserialize_i128 => visit_i128);
- deserialize_number!(deserialize_u128 => visit_u128);
- }
-
forward_to_deserialize_any! {
bool char str string bytes byte_buf option unit unit_struct
newtype_struct seq tuple tuple_struct map struct enum identifier
@@ -586,18 +562,15 @@ impl<'de, 'a> Deserializer<'de> for &'a Number {
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
+ deserialize_number!(deserialize_i128 => visit_i128);
deserialize_number!(deserialize_u8 => visit_u8);
deserialize_number!(deserialize_u16 => visit_u16);
deserialize_number!(deserialize_u32 => visit_u32);
deserialize_number!(deserialize_u64 => visit_u64);
+ deserialize_number!(deserialize_u128 => visit_u128);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);
- serde_if_integer128! {
- deserialize_number!(deserialize_i128 => visit_i128);
- deserialize_number!(deserialize_u128 => visit_u128);
- }
-
forward_to_deserialize_any! {
bool char str string bytes byte_buf option unit unit_struct
newtype_struct seq tuple tuple_struct map struct enum identifier
@@ -749,19 +722,9 @@ impl_from_unsigned!(u8, u16, u32, u64, usize);
impl_from_signed!(i8, i16, i32, i64, isize);
#[cfg(feature = "arbitrary_precision")]
-serde_if_integer128! {
- impl From<i128> for Number {
- fn from(i: i128) -> Self {
- Number { n: i.to_string() }
- }
- }
-
- impl From<u128> for Number {
- fn from(u: u128) -> Self {
- Number { n: u.to_string() }
- }
- }
-}
+impl_from_unsigned!(u128);
+#[cfg(feature = "arbitrary_precision")]
+impl_from_signed!(i128);
impl Number {
#[cfg(not(feature = "arbitrary_precision"))]
diff --git a/src/raw.rs b/src/raw.rs
index c8377ac..6aa4ffc 100644
--- a/src/raw.rs
+++ b/src/raw.rs
@@ -112,7 +112,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer};
/// raw_value: Box<RawValue>,
/// }
/// ```
-#[repr(C)]
+#[cfg_attr(not(doc), repr(transparent))]
#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
pub struct RawValue {
json: str,
diff --git a/src/read.rs b/src/read.rs
index 1319d89..fc3a3ca 100644
--- a/src/read.rs
+++ b/src/read.rs
@@ -252,7 +252,7 @@ where
Some(ch) => {
#[cfg(feature = "raw_value")]
{
- if let Some(ref mut buf) = self.raw_buffer {
+ if let Some(buf) = &mut self.raw_buffer {
buf.push(ch);
}
}
@@ -263,7 +263,7 @@ where
Some(Ok(ch)) => {
#[cfg(feature = "raw_value")]
{
- if let Some(ref mut buf) = self.raw_buffer {
+ if let Some(buf) = &mut self.raw_buffer {
buf.push(ch);
}
}
@@ -298,7 +298,7 @@ where
#[cfg(feature = "raw_value")]
fn discard(&mut self) {
if let Some(ch) = self.ch.take() {
- if let Some(ref mut buf) = self.raw_buffer {
+ if let Some(buf) = &mut self.raw_buffer {
buf.push(ch);
}
}
diff --git a/src/ser.rs b/src/ser.rs
index db77cd8..80c2deb 100644
--- a/src/ser.rs
+++ b/src/ser.rs
@@ -7,7 +7,6 @@ use alloc::vec::Vec;
use core::fmt::{self, Display};
use core::num::FpCategory;
use serde::ser::{self, Impossible, Serialize};
-use serde::serde_if_integer128;
/// A structure for serializing Rust values into JSON.
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
@@ -75,137 +74,105 @@ where
#[inline]
fn serialize_bool(self, value: bool) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_bool(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_i8(self, value: i8) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_i8(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_i16(self, value: i16) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_i16(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_i32(self, value: i32) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_i32(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_i64(self, value: i64) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_i64(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
- serde_if_integer128! {
- fn serialize_i128(self, value: i128) -> Result<()> {
- self.formatter
- .write_number_str(&mut self.writer, &value.to_string())
- .map_err(Error::io)
- }
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ self.formatter
+ .write_i128(&mut self.writer, value)
+ .map_err(Error::io)
}
#[inline]
fn serialize_u8(self, value: u8) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_u8(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_u16(self, value: u16) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_u16(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_u32(self, value: u32) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_u32(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
fn serialize_u64(self, value: u64) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_u64(&mut self.writer, value)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
- serde_if_integer128! {
- fn serialize_u128(self, value: u128) -> Result<()> {
- self.formatter
- .write_number_str(&mut self.writer, &value.to_string())
- .map_err(Error::io)
- }
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ self.formatter
+ .write_u128(&mut self.writer, value)
+ .map_err(Error::io)
}
#[inline]
fn serialize_f32(self, value: f32) -> Result<()> {
match value.classify() {
- FpCategory::Nan | FpCategory::Infinite => {
- tri!(self
- .formatter
- .write_null(&mut self.writer)
- .map_err(Error::io));
- }
- _ => {
- tri!(self
- .formatter
- .write_f32(&mut self.writer, value)
- .map_err(Error::io));
- }
+ FpCategory::Nan | FpCategory::Infinite => self
+ .formatter
+ .write_null(&mut self.writer)
+ .map_err(Error::io),
+ _ => self
+ .formatter
+ .write_f32(&mut self.writer, value)
+ .map_err(Error::io),
}
- Ok(())
}
#[inline]
fn serialize_f64(self, value: f64) -> Result<()> {
match value.classify() {
- FpCategory::Nan | FpCategory::Infinite => {
- tri!(self
- .formatter
- .write_null(&mut self.writer)
- .map_err(Error::io));
- }
- _ => {
- tri!(self
- .formatter
- .write_f64(&mut self.writer, value)
- .map_err(Error::io));
- }
+ FpCategory::Nan | FpCategory::Infinite => self
+ .formatter
+ .write_null(&mut self.writer)
+ .map_err(Error::io),
+ _ => self
+ .formatter
+ .write_f64(&mut self.writer, value)
+ .map_err(Error::io),
}
- Ok(())
}
#[inline]
@@ -217,8 +184,7 @@ where
#[inline]
fn serialize_str(self, value: &str) -> Result<()> {
- tri!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io));
- Ok(())
+ format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io)
}
#[inline]
@@ -233,11 +199,9 @@ where
#[inline]
fn serialize_unit(self) -> Result<()> {
- tri!(self
- .formatter
+ self.formatter
.write_null(&mut self.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
@@ -297,11 +261,9 @@ where
.formatter
.end_object_value(&mut self.writer)
.map_err(Error::io));
- tri!(self
- .formatter
+ self.formatter
.end_object(&mut self.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[inline]
@@ -490,11 +452,9 @@ where
}
}
}
- tri!(self
- .formatter
+ self.formatter
.end_string(&mut self.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
}
@@ -533,22 +493,17 @@ where
where
T: ?Sized + Serialize,
{
- match *self {
- Compound::Map {
- ref mut ser,
- ref mut state,
- } => {
+ match self {
+ Compound::Map { ser, state } => {
tri!(ser
.formatter
.begin_array_value(&mut ser.writer, *state == State::First)
.map_err(Error::io));
*state = State::Rest;
tri!(value.serialize(&mut **ser));
- tri!(ser
- .formatter
+ ser.formatter
.end_array_value(&mut ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
@@ -560,13 +515,10 @@ where
#[inline]
fn end(self) -> Result<()> {
match self {
- Compound::Map { ser, state } => {
- match state {
- State::Empty => {}
- _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
- }
- Ok(())
- }
+ Compound::Map { ser, state } => match state {
+ State::Empty => Ok(()),
+ _ => ser.formatter.end_array(&mut ser.writer).map_err(Error::io),
+ },
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
#[cfg(feature = "raw_value")]
@@ -647,8 +599,7 @@ where
.formatter
.end_object_value(&mut ser.writer)
.map_err(Error::io));
- tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
- Ok(())
+ ser.formatter.end_object(&mut ser.writer).map_err(Error::io)
}
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
@@ -671,11 +622,8 @@ where
where
T: ?Sized + Serialize,
{
- match *self {
- Compound::Map {
- ref mut ser,
- ref mut state,
- } => {
+ match self {
+ Compound::Map { ser, state } => {
tri!(ser
.formatter
.begin_object_key(&mut ser.writer, *state == State::First)
@@ -684,11 +632,9 @@ where
tri!(key.serialize(MapKeySerializer { ser: *ser }));
- tri!(ser
- .formatter
+ ser.formatter
.end_object_key(&mut ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
@@ -702,18 +648,16 @@ where
where
T: ?Sized + Serialize,
{
- match *self {
- Compound::Map { ref mut ser, .. } => {
+ match self {
+ Compound::Map { ser, .. } => {
tri!(ser
.formatter
.begin_object_value(&mut ser.writer)
.map_err(Error::io));
tri!(value.serialize(&mut **ser));
- tri!(ser
- .formatter
+ ser.formatter
.end_object_value(&mut ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
@@ -725,13 +669,10 @@ where
#[inline]
fn end(self) -> Result<()> {
match self {
- Compound::Map { ser, state } => {
- match state {
- State::Empty => {}
- _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
- }
- Ok(())
- }
+ Compound::Map { ser, state } => match state {
+ State::Empty => Ok(()),
+ _ => ser.formatter.end_object(&mut ser.writer).map_err(Error::io),
+ },
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
#[cfg(feature = "raw_value")]
@@ -753,22 +694,20 @@ where
where
T: ?Sized + Serialize,
{
- match *self {
+ match self {
Compound::Map { .. } => ser::SerializeMap::serialize_entry(self, key, value),
#[cfg(feature = "arbitrary_precision")]
- Compound::Number { ref mut ser, .. } => {
+ Compound::Number { ser, .. } => {
if key == crate::number::TOKEN {
- tri!(value.serialize(NumberStrEmitter(ser)));
- Ok(())
+ value.serialize(NumberStrEmitter(ser))
} else {
Err(invalid_number())
}
}
#[cfg(feature = "raw_value")]
- Compound::RawValue { ref mut ser, .. } => {
+ Compound::RawValue { ser, .. } => {
if key == crate::raw::TOKEN {
- tri!(value.serialize(RawValueStrEmitter(ser)));
- Ok(())
+ value.serialize(RawValueStrEmitter(ser))
} else {
Err(invalid_raw_value())
}
@@ -822,8 +761,7 @@ where
.formatter
.end_object_value(&mut ser.writer)
.map_err(Error::io));
- tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io));
- Ok(())
+ ser.formatter.end_object(&mut ser.writer).map_err(Error::io)
}
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
@@ -905,12 +843,10 @@ where
.formatter
.write_i8(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_i16(self, value: i16) -> Result<()> {
@@ -924,12 +860,10 @@ where
.formatter
.write_i16(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_i32(self, value: i32) -> Result<()> {
@@ -943,12 +877,10 @@ where
.formatter
.write_i32(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_i64(self, value: i64) -> Result<()> {
@@ -962,33 +894,27 @@ where
.formatter
.write_i64(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
- serde_if_integer128! {
- fn serialize_i128(self, value: i128) -> Result<()> {
- tri!(self
- .ser
- .formatter
- .begin_string(&mut self.ser.writer)
- .map_err(Error::io));
- tri!(self
- .ser
- .formatter
- .write_number_str(&mut self.ser.writer, &value.to_string())
- .map_err(Error::io));
- tri!(self
- .ser
- .formatter
- .end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
- }
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i128(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
}
fn serialize_u8(self, value: u8) -> Result<()> {
@@ -1002,12 +928,10 @@ where
.formatter
.write_u8(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_u16(self, value: u16) -> Result<()> {
@@ -1021,12 +945,10 @@ where
.formatter
.write_u16(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_u32(self, value: u32) -> Result<()> {
@@ -1040,12 +962,10 @@ where
.formatter
.write_u32(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
fn serialize_u64(self, value: u64) -> Result<()> {
@@ -1059,33 +979,27 @@ where
.formatter
.write_u64(&mut self.ser.writer, value)
.map_err(Error::io));
- tri!(self
- .ser
+ self.ser
.formatter
.end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
+ .map_err(Error::io)
}
- serde_if_integer128! {
- fn serialize_u128(self, value: u128) -> Result<()> {
- tri!(self
- .ser
- .formatter
- .begin_string(&mut self.ser.writer)
- .map_err(Error::io));
- tri!(self
- .ser
- .formatter
- .write_number_str(&mut self.ser.writer, &value.to_string())
- .map_err(Error::io));
- tri!(self
- .ser
- .formatter
- .end_string(&mut self.ser.writer)
- .map_err(Error::io));
- Ok(())
- }
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u128(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
}
fn serialize_f32(self, _value: f32) -> Result<()> {
@@ -1224,10 +1138,8 @@ impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W,
Err(invalid_number())
}
- serde_if_integer128! {
- fn serialize_i128(self, _v: i128) -> Result<()> {
- Err(invalid_number())
- }
+ fn serialize_i128(self, _v: i128) -> Result<()> {
+ Err(invalid_number())
}
fn serialize_u8(self, _v: u8) -> Result<()> {
@@ -1246,10 +1158,8 @@ impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W,
Err(invalid_number())
}
- serde_if_integer128! {
- fn serialize_u128(self, _v: u128) -> Result<()> {
- Err(invalid_number())
- }
+ fn serialize_u128(self, _v: u128) -> Result<()> {
+ Err(invalid_number())
}
fn serialize_f32(self, _v: f32) -> Result<()> {
@@ -1405,10 +1315,8 @@ impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a,
Err(ser::Error::custom("expected RawValue"))
}
- serde_if_integer128! {
- fn serialize_i128(self, _v: i128) -> Result<()> {
- Err(ser::Error::custom("expected RawValue"))
- }
+ fn serialize_i128(self, _v: i128) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
}
fn serialize_u8(self, _v: u8) -> Result<()> {
@@ -1427,10 +1335,8 @@ impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a,
Err(ser::Error::custom("expected RawValue"))
}
- serde_if_integer128! {
- fn serialize_u128(self, _v: u128) -> Result<()> {
- Err(ser::Error::custom("expected RawValue"))
- }
+ fn serialize_u128(self, _v: u128) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
}
fn serialize_f32(self, _v: f32) -> Result<()> {
@@ -1667,6 +1573,17 @@ pub trait Formatter {
writer.write_all(s.as_bytes())
}
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i128<W>(&mut self, writer: &mut W, value: i128) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
/// Writes an integer value like `123` to the specified writer.
#[inline]
fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
@@ -1711,6 +1628,17 @@ pub trait Formatter {
writer.write_all(s.as_bytes())
}
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u128<W>(&mut self, writer: &mut W, value: u128) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
/// Writes a floating point value like `-31.26e+12` to the specified writer.
#[inline]
fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
@@ -1991,13 +1919,8 @@ impl<'a> Formatter for PrettyFormatter<'a> {
where
W: ?Sized + io::Write,
{
- if first {
- tri!(writer.write_all(b"\n"));
- } else {
- tri!(writer.write_all(b",\n"));
- }
- tri!(indent(writer, self.current_indent, self.indent));
- Ok(())
+ tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
+ indent(writer, self.current_indent, self.indent)
}
#[inline]
@@ -2039,11 +1962,7 @@ impl<'a> Formatter for PrettyFormatter<'a> {
where
W: ?Sized + io::Write,
{
- if first {
- tri!(writer.write_all(b"\n"));
- } else {
- tri!(writer.write_all(b",\n"));
- }
+ tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
indent(writer, self.current_indent, self.indent)
}
@@ -2072,8 +1991,7 @@ where
{
tri!(formatter.begin_string(writer));
tri!(format_escaped_str_contents(writer, formatter, value));
- tri!(formatter.end_string(writer));
- Ok(())
+ formatter.end_string(writer)
}
fn format_escaped_str_contents<W, F>(
@@ -2105,11 +2023,11 @@ where
start = i + 1;
}
- if start != bytes.len() {
- tri!(formatter.write_string_fragment(writer, &value[start..]));
+ if start == bytes.len() {
+ return Ok(());
}
- Ok(())
+ formatter.write_string_fragment(writer, &value[start..])
}
const BB: u8 = b'b'; // \x08
@@ -2158,8 +2076,7 @@ where
T: ?Sized + Serialize,
{
let mut ser = Serializer::new(writer);
- tri!(value.serialize(&mut ser));
- Ok(())
+ value.serialize(&mut ser)
}
/// Serialize the given data structure as pretty-printed JSON into the IO
@@ -2177,8 +2094,7 @@ where
T: ?Sized + Serialize,
{
let mut ser = Serializer::pretty(writer);
- tri!(value.serialize(&mut ser));
- Ok(())
+ value.serialize(&mut ser)
}
/// Serialize the given data structure as a JSON byte vector.
diff --git a/src/value/de.rs b/src/value/de.rs
index 75e49df..9c266d0 100644
--- a/src/value/de.rs
+++ b/src/value/de.rs
@@ -14,7 +14,7 @@ use serde::de::{
self, Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess,
SeqAccess, Unexpected, VariantAccess, Visitor,
};
-use serde::{forward_to_deserialize_any, serde_if_integer128};
+use serde::forward_to_deserialize_any;
#[cfg(feature = "arbitrary_precision")]
use crate::number::NumberFromString;
@@ -228,18 +228,15 @@ impl<'de> serde::Deserializer<'de> for Value {
deserialize_number!(deserialize_i16);
deserialize_number!(deserialize_i32);
deserialize_number!(deserialize_i64);
+ deserialize_number!(deserialize_i128);
deserialize_number!(deserialize_u8);
deserialize_number!(deserialize_u16);
deserialize_number!(deserialize_u32);
deserialize_number!(deserialize_u64);
+ deserialize_number!(deserialize_u128);
deserialize_number!(deserialize_f32);
deserialize_number!(deserialize_f64);
- serde_if_integer128! {
- deserialize_number!(deserialize_i128);
- deserialize_number!(deserialize_u128);
- }
-
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
@@ -648,8 +645,8 @@ macro_rules! deserialize_value_ref_number {
where
V: Visitor<'de>,
{
- match *self {
- Value::Number(ref n) => n.deserialize_any(visitor),
+ match self {
+ Value::Number(n) => n.deserialize_any(visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -659,8 +656,8 @@ macro_rules! deserialize_value_ref_number {
where
V: Visitor<'de>,
{
- match *self {
- Value::Number(ref n) => n.$method(visitor),
+ match self {
+ Value::Number(n) => n.$method(visitor),
_ => self.deserialize_any(visitor),
}
}
@@ -710,13 +707,13 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
+ match self {
Value::Null => visitor.visit_unit(),
- Value::Bool(v) => visitor.visit_bool(v),
- Value::Number(ref n) => n.deserialize_any(visitor),
- Value::String(ref v) => visitor.visit_borrowed_str(v),
- Value::Array(ref v) => visit_array_ref(v, visitor),
- Value::Object(ref v) => visit_object_ref(v, visitor),
+ Value::Bool(v) => visitor.visit_bool(*v),
+ Value::Number(n) => n.deserialize_any(visitor),
+ Value::String(v) => visitor.visit_borrowed_str(v),
+ Value::Array(v) => visit_array_ref(v, visitor),
+ Value::Object(v) => visit_object_ref(v, visitor),
}
}
@@ -724,18 +721,15 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
deserialize_value_ref_number!(deserialize_i16);
deserialize_value_ref_number!(deserialize_i32);
deserialize_value_ref_number!(deserialize_i64);
+ deserialize_number!(deserialize_i128);
deserialize_value_ref_number!(deserialize_u8);
deserialize_value_ref_number!(deserialize_u16);
deserialize_value_ref_number!(deserialize_u32);
deserialize_value_ref_number!(deserialize_u64);
+ deserialize_number!(deserialize_u128);
deserialize_value_ref_number!(deserialize_f32);
deserialize_value_ref_number!(deserialize_f64);
- serde_if_integer128! {
- deserialize_number!(deserialize_i128);
- deserialize_number!(deserialize_u128);
- }
-
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
@@ -755,8 +749,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- let (variant, value) = match *self {
- Value::Object(ref value) => {
+ let (variant, value) = match self {
+ Value::Object(value) => {
let mut iter = value.into_iter();
let (variant, value) = match iter.next() {
Some(v) => v,
@@ -776,8 +770,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
}
(variant, Some(value))
}
- Value::String(ref variant) => (variant, None),
- ref other => {
+ Value::String(variant) => (variant, None),
+ other => {
return Err(serde::de::Error::invalid_type(
other.unexpected(),
&"string or map",
@@ -831,8 +825,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
- Value::String(ref v) => visitor.visit_borrowed_str(v),
+ match self {
+ Value::String(v) => visitor.visit_borrowed_str(v),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -848,9 +842,9 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
- Value::String(ref v) => visitor.visit_borrowed_str(v),
- Value::Array(ref v) => visit_array_ref(v, visitor),
+ match self {
+ Value::String(v) => visitor.visit_borrowed_str(v),
+ Value::Array(v) => visit_array_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -883,8 +877,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
- Value::Array(ref v) => visit_array_ref(v, visitor),
+ match self {
+ Value::Array(v) => visit_array_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -912,8 +906,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
- Value::Object(ref v) => visit_object_ref(v, visitor),
+ match self {
+ Value::Object(v) => visit_object_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -927,9 +921,9 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
where
V: Visitor<'de>,
{
- match *self {
- Value::Array(ref v) => visit_array_ref(v, visitor),
- Value::Object(ref v) => visit_object_ref(v, visitor),
+ match self {
+ Value::Array(v) => visit_array_ref(v, visitor),
+ Value::Object(v) => visit_object_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -1000,7 +994,7 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
V: Visitor<'de>,
{
match self.value {
- Some(&Value::Array(ref v)) => {
+ Some(Value::Array(v)) => {
if v.is_empty() {
visitor.visit_unit()
} else {
@@ -1027,7 +1021,7 @@ impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
V: Visitor<'de>,
{
match self.value {
- Some(&Value::Object(ref v)) => visit_object_ref(v, visitor),
+ Some(Value::Object(v)) => visit_object_ref(v, visitor),
Some(other) => Err(serde::de::Error::invalid_type(
other.unexpected(),
&"struct variant",
@@ -1156,15 +1150,12 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> {
deserialize_integer_key!(deserialize_i16 => visit_i16);
deserialize_integer_key!(deserialize_i32 => visit_i32);
deserialize_integer_key!(deserialize_i64 => visit_i64);
+ deserialize_integer_key!(deserialize_i128 => visit_i128);
deserialize_integer_key!(deserialize_u8 => visit_u8);
deserialize_integer_key!(deserialize_u16 => visit_u16);
deserialize_integer_key!(deserialize_u32 => visit_u32);
deserialize_integer_key!(deserialize_u64 => visit_u64);
-
- serde_if_integer128! {
- deserialize_integer_key!(deserialize_i128 => visit_i128);
- deserialize_integer_key!(deserialize_u128 => visit_u128);
- }
+ deserialize_integer_key!(deserialize_u128 => visit_u128);
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
@@ -1274,11 +1265,11 @@ impl Value {
#[cold]
fn unexpected(&self) -> Unexpected {
- match *self {
+ match self {
Value::Null => Unexpected::Unit,
- Value::Bool(b) => Unexpected::Bool(b),
- Value::Number(ref n) => n.unexpected(),
- Value::String(ref s) => Unexpected::Str(s),
+ Value::Bool(b) => Unexpected::Bool(*b),
+ Value::Number(n) => n.unexpected(),
+ Value::String(s) => Unexpected::Str(s),
Value::Array(_) => Unexpected::Seq,
Value::Object(_) => Unexpected::Map,
}
diff --git a/src/value/from.rs b/src/value/from.rs
index 7b37ef6..c5a6a39 100644
--- a/src/value/from.rs
+++ b/src/value/from.rs
@@ -6,9 +6,6 @@ use alloc::string::{String, ToString};
use alloc::vec::Vec;
use core::iter::FromIterator;
-#[cfg(feature = "arbitrary_precision")]
-use serde::serde_if_integer128;
-
macro_rules! from_integer {
($($ty:ident)*) => {
$(
@@ -27,10 +24,8 @@ from_integer! {
}
#[cfg(feature = "arbitrary_precision")]
-serde_if_integer128! {
- from_integer! {
- i128 u128
- }
+from_integer! {
+ i128 u128
}
impl From<f32> for Value {
@@ -268,3 +263,15 @@ impl From<()> for Value {
Value::Null
}
}
+
+impl<T> From<Option<T>> for Value
+where
+ T: Into<Value>,
+{
+ fn from(opt: Option<T>) -> Self {
+ match opt {
+ None => Value::Null,
+ Some(value) => Into::into(value),
+ }
+ }
+}
diff --git a/src/value/index.rs b/src/value/index.rs
index 0d90a5d..c74042b 100644
--- a/src/value/index.rs
+++ b/src/value/index.rs
@@ -53,20 +53,20 @@ pub trait Index: private::Sealed {
impl Index for usize {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
- match *v {
- Value::Array(ref vec) => vec.get(*self),
+ match v {
+ Value::Array(vec) => vec.get(*self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
- match *v {
- Value::Array(ref mut vec) => vec.get_mut(*self),
+ match v {
+ Value::Array(vec) => vec.get_mut(*self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
- match *v {
- Value::Array(ref mut vec) => {
+ match v {
+ Value::Array(vec) => {
let len = vec.len();
vec.get_mut(*self).unwrap_or_else(|| {
panic!(
@@ -82,23 +82,23 @@ impl Index for usize {
impl Index for str {
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
- match *v {
- Value::Object(ref map) => map.get(self),
+ match v {
+ Value::Object(map) => map.get(self),
_ => None,
}
}
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
- match *v {
- Value::Object(ref mut map) => map.get_mut(self),
+ match v {
+ Value::Object(map) => map.get_mut(self),
_ => None,
}
}
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
- if let Value::Null = *v {
+ if let Value::Null = v {
*v = Value::Object(Map::new());
}
- match *v {
- Value::Object(ref mut map) => map.entry(self.to_owned()).or_insert(Value::Null),
+ match v {
+ Value::Object(map) => map.entry(self.to_owned()).or_insert(Value::Null),
_ => panic!("cannot access key {:?} in JSON {}", self, Type(v)),
}
}
diff --git a/src/value/mod.rs b/src/value/mod.rs
index 3f00c95..470b6b2 100644
--- a/src/value/mod.rs
+++ b/src/value/mod.rs
@@ -85,10 +85,10 @@
//! # untyped_example().unwrap();
//! ```
//!
-//! [macro]: https://docs.serde.rs/serde_json/macro.json.html
-//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html
-//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html
-//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html
+//! [macro]: crate::json
+//! [from_str]: crate::de::from_str
+//! [from_slice]: crate::de::from_slice
+//! [from_reader]: crate::de::from_reader
use crate::error::Error;
use crate::io;
@@ -176,20 +176,18 @@ pub enum Value {
impl Debug for Value {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Value::Null => formatter.debug_tuple("Null").finish(),
- Value::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(),
- Value::Number(ref v) => Debug::fmt(v, formatter),
- Value::String(ref v) => formatter.debug_tuple("String").field(v).finish(),
- Value::Array(ref v) => {
- formatter.write_str("Array(")?;
- Debug::fmt(v, formatter)?;
- formatter.write_str(")")
+ match self {
+ Value::Null => formatter.write_str("Null"),
+ Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
+ Value::Number(number) => Debug::fmt(number, formatter),
+ Value::String(string) => write!(formatter, "String({:?})", string),
+ Value::Array(vec) => {
+ formatter.write_str("Array ")?;
+ Debug::fmt(vec, formatter)
}
- Value::Object(ref v) => {
- formatter.write_str("Object(")?;
- Debug::fmt(v, formatter)?;
- formatter.write_str(")")
+ Value::Object(map) => {
+ formatter.write_str("Object ")?;
+ Debug::fmt(map, formatter)
}
}
}
@@ -365,8 +363,8 @@ impl Value {
/// assert_eq!(v["b"].as_object(), None);
/// ```
pub fn as_object(&self) -> Option<&Map<String, Value>> {
- match *self {
- Value::Object(ref map) => Some(map),
+ match self {
+ Value::Object(map) => Some(map),
_ => None,
}
}
@@ -383,8 +381,8 @@ impl Value {
/// assert_eq!(v, json!({ "a": {} }));
/// ```
pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> {
- match *self {
- Value::Object(ref mut map) => Some(map),
+ match self {
+ Value::Object(map) => Some(map),
_ => None,
}
}
@@ -424,8 +422,8 @@ impl Value {
/// assert_eq!(v["b"].as_array(), None);
/// ```
pub fn as_array(&self) -> Option<&Vec<Value>> {
- match *self {
- Value::Array(ref array) => Some(&*array),
+ match self {
+ Value::Array(array) => Some(array),
_ => None,
}
}
@@ -442,8 +440,8 @@ impl Value {
/// assert_eq!(v, json!({ "a": [] }));
/// ```
pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
- match *self {
- Value::Array(ref mut list) => Some(list),
+ match self {
+ Value::Array(list) => Some(list),
_ => None,
}
}
@@ -491,8 +489,8 @@ impl Value {
/// println!("The value is: {}", v["a"].as_str().unwrap());
/// ```
pub fn as_str(&self) -> Option<&str> {
- match *self {
- Value::String(ref s) => Some(s),
+ match self {
+ Value::String(s) => Some(s),
_ => None,
}
}
@@ -537,8 +535,8 @@ impl Value {
/// assert!(!v["c"].is_i64());
/// ```
pub fn is_i64(&self) -> bool {
- match *self {
- Value::Number(ref n) => n.is_i64(),
+ match self {
+ Value::Number(n) => n.is_i64(),
_ => false,
}
}
@@ -562,8 +560,8 @@ impl Value {
/// assert!(!v["c"].is_u64());
/// ```
pub fn is_u64(&self) -> bool {
- match *self {
- Value::Number(ref n) => n.is_u64(),
+ match self {
+ Value::Number(n) => n.is_u64(),
_ => false,
}
}
@@ -588,8 +586,8 @@ impl Value {
/// assert!(!v["c"].is_f64());
/// ```
pub fn is_f64(&self) -> bool {
- match *self {
- Value::Number(ref n) => n.is_f64(),
+ match self {
+ Value::Number(n) => n.is_f64(),
_ => false,
}
}
@@ -608,8 +606,8 @@ impl Value {
/// assert_eq!(v["c"].as_i64(), None);
/// ```
pub fn as_i64(&self) -> Option<i64> {
- match *self {
- Value::Number(ref n) => n.as_i64(),
+ match self {
+ Value::Number(n) => n.as_i64(),
_ => None,
}
}
@@ -627,8 +625,8 @@ impl Value {
/// assert_eq!(v["c"].as_u64(), None);
/// ```
pub fn as_u64(&self) -> Option<u64> {
- match *self {
- Value::Number(ref n) => n.as_u64(),
+ match self {
+ Value::Number(n) => n.as_u64(),
_ => None,
}
}
@@ -646,8 +644,8 @@ impl Value {
/// assert_eq!(v["c"].as_f64(), Some(-64.0));
/// ```
pub fn as_f64(&self) -> Option<f64> {
- match *self {
- Value::Number(ref n) => n.as_f64(),
+ match self {
+ Value::Number(n) => n.as_f64(),
_ => None,
}
}
diff --git a/src/value/ser.rs b/src/value/ser.rs
index 179380a..a29814e 100644
--- a/src/value/ser.rs
+++ b/src/value/ser.rs
@@ -5,27 +5,26 @@ use crate::value::{to_value, Value};
use alloc::borrow::ToOwned;
use alloc::string::{String, ToString};
use alloc::vec::Vec;
+#[cfg(not(feature = "arbitrary_precision"))]
+use core::convert::TryFrom;
use core::fmt::Display;
use core::result;
use serde::ser::{Impossible, Serialize};
-#[cfg(feature = "arbitrary_precision")]
-use serde::serde_if_integer128;
-
impl Serialize for Value {
#[inline]
fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
- match *self {
+ match self {
Value::Null => serializer.serialize_unit(),
- Value::Bool(b) => serializer.serialize_bool(b),
- Value::Number(ref n) => n.serialize(serializer),
- Value::String(ref s) => serializer.serialize_str(s),
- Value::Array(ref v) => v.serialize(serializer),
+ Value::Bool(b) => serializer.serialize_bool(*b),
+ Value::Number(n) => n.serialize(serializer),
+ Value::String(s) => serializer.serialize_str(s),
+ Value::Array(v) => v.serialize(serializer),
#[cfg(any(feature = "std", feature = "alloc"))]
- Value::Object(ref m) => {
+ Value::Object(m) => {
use serde::ser::SerializeMap;
let mut map = tri!(serializer.serialize_map(Some(m.len())));
for (k, v) in m {
@@ -95,11 +94,22 @@ impl serde::Serializer for Serializer {
Ok(Value::Number(value.into()))
}
- #[cfg(feature = "arbitrary_precision")]
- serde_if_integer128! {
- fn serialize_i128(self, value: i128) -> Result<Value> {
+ fn serialize_i128(self, value: i128) -> Result<Value> {
+ #[cfg(feature = "arbitrary_precision")]
+ {
Ok(Value::Number(value.into()))
}
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ if let Ok(value) = u64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else if let Ok(value) = i64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else {
+ Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0))
+ }
+ }
}
#[inline]
@@ -122,11 +132,20 @@ impl serde::Serializer for Serializer {
Ok(Value::Number(value.into()))
}
- #[cfg(feature = "arbitrary_precision")]
- serde_if_integer128! {
- fn serialize_u128(self, value: u128) -> Result<Value> {
+ fn serialize_u128(self, value: u128) -> Result<Value> {
+ #[cfg(feature = "arbitrary_precision")]
+ {
Ok(Value::Number(value.into()))
}
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ if let Ok(value) = u64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else {
+ Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0))
+ }
+ }
}
#[inline]
@@ -195,7 +214,7 @@ impl serde::Serializer for Serializer {
T: ?Sized + Serialize,
{
let mut values = Map::new();
- values.insert(String::from(variant), tri!(to_value(&value)));
+ values.insert(String::from(variant), tri!(to_value(value)));
Ok(Value::Object(values))
}
@@ -273,9 +292,9 @@ impl serde::Serializer for Serializer {
})
}
- fn collect_str<T: ?Sized>(self, value: &T) -> Result<Value>
+ fn collect_str<T>(self, value: &T) -> Result<Value>
where
- T: Display,
+ T: ?Sized + Display,
{
Ok(Value::String(value.to_string()))
}
@@ -314,7 +333,7 @@ impl serde::ser::SerializeSeq for SerializeVec {
where
T: ?Sized + Serialize,
{
- self.vec.push(tri!(to_value(&value)));
+ self.vec.push(tri!(to_value(value)));
Ok(())
}
@@ -363,7 +382,7 @@ impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
where
T: ?Sized + Serialize,
{
- self.vec.push(tri!(to_value(&value)));
+ self.vec.push(tri!(to_value(value)));
Ok(())
}
@@ -384,10 +403,8 @@ impl serde::ser::SerializeMap for SerializeMap {
where
T: ?Sized + Serialize,
{
- match *self {
- SerializeMap::Map {
- ref mut next_key, ..
- } => {
+ match self {
+ SerializeMap::Map { next_key, .. } => {
*next_key = Some(tri!(key.serialize(MapKeySerializer)));
Ok(())
}
@@ -402,16 +419,13 @@ impl serde::ser::SerializeMap for SerializeMap {
where
T: ?Sized + Serialize,
{
- match *self {
- SerializeMap::Map {
- ref mut map,
- ref mut next_key,
- } => {
+ match self {
+ SerializeMap::Map { map, next_key } => {
let key = next_key.take();
// Panic because this indicates a bug in the program rather than an
// expected failure.
let key = key.expect("serialize_value called before serialize_key");
- map.insert(key, tri!(to_value(&value)));
+ map.insert(key, tri!(to_value(value)));
Ok(())
}
#[cfg(feature = "arbitrary_precision")]
@@ -606,9 +620,9 @@ impl serde::Serializer for MapKeySerializer {
Err(key_must_be_a_string())
}
- fn collect_str<T: ?Sized>(self, value: &T) -> Result<String>
+ fn collect_str<T>(self, value: &T) -> Result<String>
where
- T: Display,
+ T: ?Sized + Display,
{
Ok(value.to_string())
}
@@ -622,10 +636,10 @@ impl serde::ser::SerializeStruct for SerializeMap {
where
T: ?Sized + Serialize,
{
- match *self {
+ match self {
SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value),
#[cfg(feature = "arbitrary_precision")]
- SerializeMap::Number { ref mut out_value } => {
+ SerializeMap::Number { out_value } => {
if key == crate::number::TOKEN {
*out_value = Some(value.serialize(NumberValueEmitter)?);
Ok(())
@@ -634,7 +648,7 @@ impl serde::ser::SerializeStruct for SerializeMap {
}
}
#[cfg(feature = "raw_value")]
- SerializeMap::RawValue { ref mut out_value } => {
+ SerializeMap::RawValue { out_value } => {
if key == crate::raw::TOKEN {
*out_value = Some(value.serialize(RawValueEmitter)?);
Ok(())
@@ -668,7 +682,7 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant {
where
T: ?Sized + Serialize,
{
- self.map.insert(String::from(key), tri!(to_value(&value)));
+ self.map.insert(String::from(key), tri!(to_value(value)));
Ok(())
}
diff --git a/tests/debug.rs b/tests/debug.rs
index d2d8448..8ddcf5a 100644
--- a/tests/debug.rs
+++ b/tests/debug.rs
@@ -1,3 +1,4 @@
+use indoc::indoc;
use serde_json::{json, Number, Value};
#[test]
@@ -26,6 +27,8 @@ fn value_number() {
assert_eq!(format!("{:?}", json!(1)), "Number(1)");
assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
+ assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1"
+ assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41");
}
#[test]
@@ -35,12 +38,12 @@ fn value_string() {
#[test]
fn value_array() {
- assert_eq!(format!("{:?}", json!([])), "Array([])");
+ assert_eq!(format!("{:?}", json!([])), "Array []");
}
#[test]
fn value_object() {
- assert_eq!(format!("{:?}", json!({})), "Object({})");
+ assert_eq!(format!("{:?}", json!({})), "Object {}");
}
#[test]
@@ -50,19 +53,29 @@ fn error() {
assert_eq!(format!("{:?}", err), expected);
}
-const INDENTED_EXPECTED: &str = r#"Object({
- "array": Array([
- Number(
- 0,
- ),
- Number(
- 1,
- ),
- ]),
-})"#;
-
#[test]
fn indented() {
- let j = json!({ "array": [0, 1] });
- assert_eq!(format!("{:#?}", j), INDENTED_EXPECTED);
+ let j = json!({
+ "Array": [true],
+ "Bool": true,
+ "EmptyArray": [],
+ "EmptyObject": {},
+ "Null": null,
+ "Number": 1,
+ "String": "...",
+ });
+ let expected = indoc! {r#"
+ Object {
+ "Array": Array [
+ Bool(true),
+ ],
+ "Bool": Bool(true),
+ "EmptyArray": Array [],
+ "EmptyObject": Object {},
+ "Null": Null,
+ "Number": Number(1),
+ "String": String("..."),
+ }"#
+ };
+ assert_eq!(format!("{:#?}", j), expected);
}
diff --git a/tests/macros/mod.rs b/tests/macros/mod.rs
index 8ac4619..aaf820f 100644
--- a/tests/macros/mod.rs
+++ b/tests/macros/mod.rs
@@ -1,3 +1,5 @@
+#![allow(unused_macro_rules)]
+
macro_rules! json_str {
([]) => {
"[]"
diff --git a/tests/regression/issue795.rs b/tests/regression/issue795.rs
index 06b6872..bb82852 100644
--- a/tests/regression/issue795.rs
+++ b/tests/regression/issue795.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::assertions_on_result_states)]
+
use serde::de::{
Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor,
};
diff --git a/tests/regression/issue845.rs b/tests/regression/issue845.rs
index dcca556..56037ae 100644
--- a/tests/regression/issue845.rs
+++ b/tests/regression/issue845.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757
+
use serde::{Deserialize, Deserializer};
use std::convert::TryFrom;
use std::fmt::{self, Display};
diff --git a/tests/regression/issue953.rs b/tests/regression/issue953.rs
new file mode 100644
index 0000000..771aa52
--- /dev/null
+++ b/tests/regression/issue953.rs
@@ -0,0 +1,9 @@
+use serde_json::Value;
+
+#[test]
+fn test() {
+ let x1 = serde_json::from_str::<Value>("18446744073709551615.");
+ assert!(x1.is_err());
+ let x2 = serde_json::from_str::<Value>("18446744073709551616.");
+ assert!(x2.is_err());
+}
diff --git a/tests/stream.rs b/tests/stream.rs
index ca54e9a..ec6b9e3 100644
--- a/tests/stream.rs
+++ b/tests/stream.rs
@@ -1,4 +1,5 @@
#![cfg(not(feature = "preserve_order"))]
+#![allow(clippy::assertions_on_result_states)]
use serde_json::{json, Deserializer, Value};
diff --git a/tests/test.rs b/tests/test.rs
index b11635e..f62a545 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -1,10 +1,11 @@
#![cfg(not(feature = "preserve_order"))]
#![allow(
+ clippy::assertions_on_result_states,
clippy::cast_precision_loss,
+ clippy::derive_partial_eq_without_eq,
clippy::excessive_precision,
clippy::float_cmp,
clippy::items_after_statements,
- clippy::let_underscore_drop,
clippy::shadow_unrelated,
clippy::too_many_lines,
clippy::unreadable_literal,
@@ -93,7 +94,7 @@ where
let s = to_string(value).unwrap();
assert_eq!(s, out);
- let v = to_value(&value).unwrap();
+ let v = to_value(value).unwrap();
let s = to_string(&v).unwrap();
assert_eq!(s, out);
}
@@ -109,7 +110,7 @@ where
let s = to_string_pretty(value).unwrap();
assert_eq!(s, out);
- let v = to_value(&value).unwrap();
+ let v = to_value(value).unwrap();
let s = to_string_pretty(&v).unwrap();
assert_eq!(s, out);
}
@@ -1105,7 +1106,7 @@ fn test_parse_string() {
]);
test_parse_ok(vec![
- ("\"\"", "".to_string()),
+ ("\"\"", String::new()),
("\"foo\"", "foo".to_string()),
(" \"foo\" ", "foo".to_string()),
("\"\\\"\"", "\"".to_string()),
@@ -1926,7 +1927,7 @@ fn test_deny_float_key() {
// map with float key
let map = treemap!(Float => "x");
- assert!(serde_json::to_value(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
}
#[test]
@@ -2179,6 +2180,27 @@ fn test_integer128() {
]);
}
+#[test]
+fn test_integer128_to_value() {
+ let signed = &[i128::from(i64::min_value()), i128::from(u64::max_value())];
+ let unsigned = &[0, u128::from(u64::max_value())];
+
+ for integer128 in signed {
+ let expected = integer128.to_string();
+ assert_eq!(to_value(integer128).unwrap().to_string(), expected);
+ }
+
+ for integer128 in unsigned {
+ let expected = integer128.to_string();
+ assert_eq!(to_value(integer128).unwrap().to_string(), expected);
+ }
+
+ if !cfg!(feature = "arbitrary_precision") {
+ let err = to_value(u128::from(u64::max_value()) + 1).unwrap_err();
+ assert_eq!(err.to_string(), "number out of range");
+ }
+}
+
#[cfg(feature = "raw_value")]
#[test]
fn test_borrowed_raw_value() {
diff --git a/tests/ui/missing_colon.stderr b/tests/ui/missing_colon.stderr
index 9b83c17..1515211 100644
--- a/tests/ui/missing_colon.stderr
+++ b/tests/ui/missing_colon.stderr
@@ -4,4 +4,9 @@ error: unexpected end of macro invocation
4 | json!({ "a" });
| ^^^^^^^^^^^^^^ missing tokens in macro arguments
|
- = note: this error originates in the macro `json_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+note: while trying to match `@`
+ --> src/macros.rs
+ |
+ | (@array [$($elems:expr,)*]) => {
+ | ^
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/missing_comma.stderr b/tests/ui/missing_comma.stderr
index bd911d0..bafa0f8 100644
--- a/tests/ui/missing_comma.stderr
+++ b/tests/ui/missing_comma.stderr
@@ -5,3 +5,9 @@ error: no rules expected the token `"2"`
| -^^^ no rules expected this token in macro call
| |
| help: missing comma here
+ |
+note: while trying to match `,`
+ --> src/macros.rs
+ |
+ | ($e:expr , $($tt:tt)*) => {};
+ | ^
diff --git a/tests/ui/missing_value.stderr b/tests/ui/missing_value.stderr
index d538d96..9c9de99 100644
--- a/tests/ui/missing_value.stderr
+++ b/tests/ui/missing_value.stderr
@@ -4,4 +4,9 @@ error: unexpected end of macro invocation
4 | json!({ "a" : });
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
- = note: this error originates in the macro `json_internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+note: while trying to match `@`
+ --> src/macros.rs
+ |
+ | (@array [$($elems:expr,)*]) => {
+ | ^
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/tests/ui/parse_expr.stderr b/tests/ui/parse_expr.stderr
index 6959673..cd3e1c9 100644
--- a/tests/ui/parse_expr.stderr
+++ b/tests/ui/parse_expr.stderr
@@ -3,3 +3,9 @@ error: no rules expected the token `~`
|
4 | json!({ "a" : ~ });
| ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$e:expr`
+ --> src/macros.rs
+ |
+ | ($e:expr , $($tt:tt)*) => {};
+ | ^^^^^^^
diff --git a/tests/ui/unexpected_after_array_element.stderr b/tests/ui/unexpected_after_array_element.stderr
index f745a21..ef449f7 100644
--- a/tests/ui/unexpected_after_array_element.stderr
+++ b/tests/ui/unexpected_after_array_element.stderr
@@ -3,3 +3,5 @@ error: no rules expected the token `=>`
|
4 | json!([ true => ]);
| ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/tests/ui/unexpected_after_map_entry.stderr b/tests/ui/unexpected_after_map_entry.stderr
index a18c9b4..c62d90b 100644
--- a/tests/ui/unexpected_after_map_entry.stderr
+++ b/tests/ui/unexpected_after_map_entry.stderr
@@ -3,3 +3,5 @@ error: no rules expected the token `=>`
|
4 | json!({ "k": true => });
| ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/tests/ui/unexpected_colon.stderr b/tests/ui/unexpected_colon.stderr
index ed038f6..7e47726 100644
--- a/tests/ui/unexpected_colon.stderr
+++ b/tests/ui/unexpected_colon.stderr
@@ -3,3 +3,5 @@ error: no rules expected the token `:`
|
4 | json!({ : true });
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/tests/ui/unexpected_comma.stderr b/tests/ui/unexpected_comma.stderr
index a4309c4..552f399 100644
--- a/tests/ui/unexpected_comma.stderr
+++ b/tests/ui/unexpected_comma.stderr
@@ -3,3 +3,5 @@ error: no rules expected the token `,`
|
4 | json!({ "a" , "b": true });
| ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro