diff --git a/Cargo.lock b/Cargo.lock index 6ec83f75..6ea42f9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,12 +13,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "associative-cache" version = "1.0.1" @@ -110,19 +104,6 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if 1.0.0", - "ryu", - "static_assertions", -] - [[package]] name = "libc" version = "0.2.99" @@ -273,10 +254,11 @@ checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" [[package]] name = "serde_json" -version = "1.0.53" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" dependencies = [ "itoa", - "lexical-core", "ryu", "serde", ] @@ -287,12 +269,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "version_check" version = "0.9.3" diff --git a/Cargo.toml b/Cargo.toml index 7d9553d4..2a7a26ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,10 +48,20 @@ classifiers = [ "Typing :: Typed", ] +[features] +default = [] + +# Use SIMD intrinsics. This requires Rust on the nightly channel. +unstable-simd = [ + "bytecount/generic-simd", + "bytecount/runtime-dispatch-simd", + "encoding_rs/simd-accel", +] + [dependencies] ahash = { version = "0.7", default_features = false } associative-cache = { version = "1" } -bytecount = { version = "^0.6.2", default_features = false, features = ["generic-simd", "runtime-dispatch-simd"] } +bytecount = { version = "^0.6.2", default_features = false, features = ["runtime-dispatch-simd"] } chrono = { version = "0.4", default_features = false } encoding_rs = { version = "0.8", default_features = false } inlinable_string = { version = "0.1" } @@ -60,12 +70,9 @@ once_cell = { version = "1", default_features = false } pyo3 = { version = "^0.14.2", default_features = false, features = ["extension-module"]} ryu = { version = "1", default_features = false } serde = { version = "1", default_features = false } -serde_json = { path = "./json", default_features = false, features = ["std"] } +serde_json = { version = "^1.0.66", default_features = false, features = ["std", "float_roundtrip"] } smallvec = { version = "^1.6", default_features = false, features = ["union", "write"] } -[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "i686", target_arch = "armv7"))'.dependencies] -encoding_rs = { version = "0.8", default_features = false, features = ["simd-accel"] } - [profile.release] codegen-units = 1 debug = false diff --git a/README.md b/README.md index f41108f9..8e1bbf92 100644 --- a/README.md +++ b/README.md @@ -1162,17 +1162,22 @@ If someone implements it well. To package orjson requires [Rust](https://www.rust-lang.org/) and the [maturin](https://github.com/PyO3/maturin) build tool. -This is an example for the x86_64-unknown-linux-gnu target: +This is an example for the x86_64-unknown-linux-gnu target on the Rust +nightly channel: ```sh -RUSTFLAGS="-C target-cpu=k8" maturin build --no-sdist --release --strip +RUSTFLAGS="-C target-cpu=k8" maturin build --no-sdist --release --strip --cargo-extra-args="--features=unstable-simd" ```` +To build on the stable channel, do not specify `--features=unstable-simd`. It +is disabled by default. There is a performance benefit of something like +10% when building on nightly with `unstable-simd`. The explicit `RUSTFLAGS` enables SSE2 on amd64. aarch64 does not need any `target-feature` specified. -The project's own CI tests against `nightly-2021-08-04`. It is prudent to -pin this version because Rust nightly can introduce breaking changes. +The project's own CI tests against `nightly-2021-08-04` and stable 1.54. It +is prudent to pin the nightly version because that channel can introduce +breaking changes. orjson is tested for amd64 and aarch64 on Linux and amd64 on macOS and Windows. It may not work on 32-bit targets. diff --git a/ci/azure-debug.yml b/ci/azure-debug.yml index b62042d0..2b2fbf52 100644 --- a/ci/azure-debug.yml +++ b/ci/azure-debug.yml @@ -1,19 +1,30 @@ parameters: - interpreter: '' - manylinux: '' - path: '' - toolchain: '' + - name: extra + type: string + default : '' + - name: interpreter + type: string + default : '' + - name: manylinux + type: string + default : '' + - name: path + type: string + default : '' + - name: toolchain + type: string + default : '' steps: - bash: curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain $(toolchain) --profile minimal -y displayName: rustup - bash: PATH=$(path) rustup default $(toolchain) displayName: ensure toolchain -- bash: PATH=$(path) pip install --user --upgrade pip maturin==0.11.2 +- bash: PATH=$(path) $(interpreter) -m pip install --user --upgrade pip maturin==0.11.2 displayName: build dependencies - bash: PATH=$(path) $(interpreter) -m pip install --user -r test/requirements.txt -r integration/requirements.txt displayName: test dependencies -- bash: PATH=$(path) maturin build --no-sdist --strip --compatibility $(manylinux) --interpreter $(interpreter) +- bash: PATH=$(path) maturin build --no-sdist --strip $(extra) --compatibility $(manylinux) --interpreter $(interpreter) env: RUSTFLAGS: "-C target-cpu=k8" displayName: build debug diff --git a/ci/azure-linux-container.yml b/ci/azure-linux-container.yml index 67ea211c..90726bdb 100644 --- a/ci/azure-linux-container.yml +++ b/ci/azure-linux-container.yml @@ -1,24 +1,37 @@ parameters: - interpreter: '' - manylinux: '' - path: '' - toolchain: '' - verifyManylinux: '' + - name: extra + type: string + default : '' + - name: interpreter + type: string + default : '' + - name: manylinux + type: string + default : '' + - name: path + type: string + default : '' + - name: toolchain + type: string + default : '' + - name: verifyManylinux + type: boolean + default : true steps: - bash: curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain $(toolchain) --profile minimal -y displayName: rustup - bash: PATH=$(path) rustup default $(toolchain) displayName: ensure toolchain -- bash: PATH=$(path) pip install --user --upgrade pip maturin==0.11.2 auditwheel +- bash: PATH=$(path) $(interpreter) -m pip install --user --upgrade pip maturin==0.11.2 auditwheel displayName: build dependencies -- bash: PATH=$(path) maturin build --no-sdist --release --strip --compatibility $(manylinux) --interpreter $(interpreter) +- bash: PATH=$(path) maturin build --no-sdist --release --strip $(extra) --compatibility $(manylinux) --interpreter $(interpreter) env: RUSTFLAGS: "-C target-cpu=k8" displayName: build - bash: PATH=$(path) $(interpreter) -m auditwheel repair target/wheels/orjson*.whl displayName: verify that wheel conforms to manylinux tag - condition: eq('${{ parameters.verifyManylinux }}', true) + condition: eq(${{ parameters.verifyManylinux }}, true) - bash: PATH=$(path) $(interpreter) -m pip install --user target/wheels/orjson*.whl displayName: install - bash: PATH=$(path) $(interpreter) -m pip install --user -r test/requirements.txt -r integration/requirements.txt diff --git a/ci/azure-macos.yml b/ci/azure-macos.yml index d827aa85..75f7d3db 100644 --- a/ci/azure-macos.yml +++ b/ci/azure-macos.yml @@ -11,7 +11,7 @@ steps: displayName: build dependencies - bash: pip install -r test/requirements.txt -r integration/requirements.txt displayName: test dependencies -- bash: PATH=$HOME/.cargo/bin:$PATH maturin build --no-sdist --release --strip --interpreter $(interpreter) +- bash: PATH=$HOME/.cargo/bin:$PATH maturin build --no-sdist --release --strip --cargo-extra-args="--features=unstable-simd" --interpreter $(interpreter) env: RUSTFLAGS: "-C target-cpu=k8" displayName: build @@ -29,7 +29,7 @@ steps: displayName: http - bash: rustup target add aarch64-apple-darwin displayName: rustup target -- bash: PATH=$HOME/.cargo/bin:$PATH PYO3_CROSS_LIB_DIR=$(python -c "import sysconfig;print(sysconfig.get_config_var('LIBDIR'))") maturin build --no-sdist --release --strip --interpreter $(interpreter) --universal2 +- bash: PATH=$HOME/.cargo/bin:$PATH PYO3_CROSS_LIB_DIR=$(python -c "import sysconfig;print(sysconfig.get_config_var('LIBDIR'))") maturin build --no-sdist --release --strip --cargo-extra-args="--features=unstable-simd" --interpreter $(interpreter) --universal2 displayName: build universal2 - bash: pip install --force-reinstall target/wheels/orjson*universal2.whl displayName: install universal2 diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 21b24b95..ad7681b2 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -11,13 +11,25 @@ jobs: - job: linux_sdist pool: vmImage: ubuntu-20.04 + container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: interpreter: python3.9 + path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp39-cp39/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin + target: x86_64-unknown-linux-gnu + steps: + - checkout: self + - template: ./azure-sdist.yml + +- job: linux_stable + pool: + vmImage: ubuntu-20.04 + container: quay.io/pypa/manylinux_2_24_x86_64:latest + variables: + interpreter: python3.9 + path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp39-cp39/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin + target: x86_64-unknown-linux-gnu + toolchain: 1.54.0 steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.9' - addToPath: true - checkout: self - template: ./azure-sdist.yml @@ -26,10 +38,10 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.9 manylinux: off path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp39-cp39/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin - verifyManylinux: false steps: - checkout: self - template: ./azure-debug.yml @@ -39,6 +51,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.10 manylinux: 2_24 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp310-cp310/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin @@ -52,6 +65,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.9 manylinux: 2_24 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp39-cp39/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin @@ -65,6 +79,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.8 manylinux: 2_24 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp38-cp38/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin @@ -78,6 +93,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux_2_24_x86_64:latest variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.7 manylinux: 2_24 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp37-cp37m/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin @@ -91,6 +107,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux2014_x86_64:2021-07-03-d4d5413 variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.9 manylinux: 2014 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp39-cp39/bin:/opt/rh/devtoolset-9/root/usr/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin @@ -104,6 +121,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux2014_x86_64:2021-07-03-d4d5413 variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.8 manylinux: 2014 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp38-cp38/bin:/opt/rh/devtoolset-9/root/usr/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin @@ -117,6 +135,7 @@ jobs: vmImage: ubuntu-20.04 container: quay.io/pypa/manylinux2014_x86_64:2021-07-03-d4d5413 variables: + extra: '--cargo-extra-args="--features=unstable-simd"' interpreter: python3.7 manylinux: 2014 path: /home/vsts_azpcontainer/.local/bin:/home/vsts_azpcontainer/.cargo/bin:/opt/python/cp37-cp37m/bin:/opt/rh/devtoolset-9/root/usr/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin diff --git a/ci/azure-sdist.yml b/ci/azure-sdist.yml index eb4d32eb..29790e23 100644 --- a/ci/azure-sdist.yml +++ b/ci/azure-sdist.yml @@ -1,28 +1,34 @@ parameters: - interpreter: '' - target: '' - toolchain: '' + - name: interpreter + type: string + default : '' + - name: path + type: string + default : '' + - name: toolchain + type: string + default : '' steps: - bash: curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain $(toolchain) --profile minimal -y displayName: rustup -- bash: rustup default $(toolchain) +- bash: PATH=$(path) rustup default $(toolchain) displayName: ensure toolchain -- bash: pip install --upgrade pip maturin==0.11.2 +- bash: PATH=$(path) $(interpreter) -m pip install --user --upgrade pip maturin==0.11.2 displayName: build dependencies -- bash: python3 -m pip install -r test/requirements.txt -r integration/requirements.txt +- bash: PATH=$(path) $(interpreter) -m pip install --user -r test/requirements.txt -r integration/requirements.txt displayName: test dependencies -- bash: maturin sdist +- bash: PATH=$(path) maturin sdist displayName: package sdist -- bash: python3 -m pip install target/wheels/orjson*.tar.gz +- bash: PATH=$(path) $(interpreter) -m pip install --user target/wheels/orjson*.tar.gz displayName: install -- bash: pytest -v test +- bash: PATH=$(path) pytest -v test displayName: pytest -- bash: ./integration/run thread +- bash: PATH=$(path) ./integration/run thread displayName: thread -- bash: ./integration/run http +- bash: PATH=$(path) ./integration/run http displayName: http -- bash: ./ci/deploy target/wheels/*.tar.gz +- bash: PATH=$(path) ./ci/deploy target/wheels/*.tar.gz displayName: deploy env: MATURIN_PASSWORD: $(TWINE_PASSWORD) diff --git a/ci/drone.yml b/ci/drone.yml index a9051366..75c80b9d 100644 --- a/ci/drone.yml +++ b/ci/drone.yml @@ -16,7 +16,7 @@ steps: commands: - curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-08-04 --profile minimal -y - python3.10 -m pip install --user --upgrade pip maturin==0.11.2 - - maturin build --no-sdist --release --strip --compatibility 2_24 --interpreter python3.10 + - maturin build --no-sdist --release --strip --compatibility 2_24 --cargo-extra-args="--features=unstable-simd" --interpreter python3.10 - python3.10 -m pip install --user target/wheels/orjson*.whl - python3.10 -m pip install --user -r test/requirements.txt -r integration/requirements.txt - pytest -s -rxX -v test @@ -40,7 +40,7 @@ steps: commands: - curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-08-04 --profile minimal -y - python3.9 -m pip install --user --upgrade pip maturin==0.11.2 - - maturin build --no-sdist --release --strip --compatibility manylinux_2_24 --interpreter python3.9 + - maturin build --no-sdist --release --strip --compatibility 2_24 --cargo-extra-args="--features=unstable-simd" --interpreter python3.9 - python3.9 -m pip install --user target/wheels/orjson*.whl - python3.9 -m pip install --user -r test/requirements.txt -r integration/requirements.txt - pytest -s -rxX -v test @@ -64,7 +64,7 @@ steps: commands: - curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-08-04 --profile minimal -y - python3.8 -m pip install --user --upgrade pip maturin==0.11.2 - - maturin build --no-sdist --release --strip --compatibility manylinux_2_24 --interpreter python3.8 + - maturin build --no-sdist --release --strip --compatibility 2_24 --cargo-extra-args="--features=unstable-simd" --interpreter python3.8 - python3.8 -m pip install --user target/wheels/orjson*.whl - python3.8 -m pip install --user -r test/requirements.txt -r integration/requirements.txt - pytest -s -rxX -v test @@ -88,7 +88,7 @@ steps: commands: - curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-08-04 --profile minimal -y - python3.7 -m pip install --user --upgrade pip maturin==0.11.2 - - maturin build --no-sdist --release --strip --compatibility manylinux_2_24 --interpreter python3.7 + - maturin build --no-sdist --release --strip --compatibility 2_24 --cargo-extra-args="--features=unstable-simd" --interpreter python3.7 - python3.7 -m pip install --user target/wheels/orjson*.whl - python3.7 -m pip install --user -r test/requirements.txt -r integration/requirements.txt - pytest -s -rxX -v test diff --git a/json/Cargo.toml b/json/Cargo.toml deleted file mode 100644 index b614c13b..00000000 --- a/json/Cargo.toml +++ /dev/null @@ -1,75 +0,0 @@ -[package] -name = "serde_json" -version = "1.0.53" # remember to update html_root_url -authors = ["Erick Tryzelaar ", "David Tolnay "] -license = "MIT OR Apache-2.0" -description = "A JSON serialization file format" -repository = "https://github.com/serde-rs/json" -documentation = "http://docs.serde.rs/serde_json/" -keywords = ["json", "serde", "serialization"] -categories = ["encoding"] -readme = "README.md" -include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] -edition = "2018" - -[dependencies] -serde = { version = "1.0.100", default-features = false } -indexmap = { version = "1.2", optional = true } -itoa = { version = "0.4.3", default-features = false } -ryu = "1.0" -lexical-core = { version = "0.7", default_features = false, features = ["correct", "format", "ryu"]} - -[dev-dependencies] -automod = "0.1" -rustversion = "1.0" -serde_bytes = "0.11" -serde_derive = "1.0" -serde_stacker = "0.1" -trybuild = { version = "1.0.19", features = ["diff"] } - -[workspace] -members = ["tests/crate"] - -[package.metadata.docs.rs] -features = ["raw_value", "unbounded_depth"] -targets = ["x86_64-unknown-linux-gnu"] - -[package.metadata.playground] -features = ["raw_value"] - - -### FEATURES ################################################################# - -[features] -default = ["std"] - -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"] - -# Use a different representation for the map type of serde_json::Value. -# 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"] - -# Use an arbitrary precision number representation for serde_json::Number. This -# allows JSON numbers of arbitrary size/precision to be read into a Number and -# written back to a JSON string without loss of precision. -arbitrary_precision = [] - -# Provide a RawValue type that can hold unprocessed JSON during deserialization. -raw_value = [] - -# Provide a method disable_recursion_limit to parse arbitrarily deep JSON -# structures without any consideration for overflowing the stack. When using -# this feature, you will want to provide some other way to protect against stack -# overflows, such as by wrapping your Deserializer in the dynamically growing -# stack adapter provided by the serde_stacker crate. Additionally you will need -# to be careful around other recursive operations on the parsed result which may -# overflow the stack after deserialization has completed, including, but not -# limited to, Display and Debug and Drop impls. -unbounded_depth = [] diff --git a/json/README.md b/json/README.md deleted file mode 100644 index d884257e..00000000 --- a/json/README.md +++ /dev/null @@ -1 +0,0 @@ -This is serde-json with perfect_float.patch applied. diff --git a/json/perfect_float.patch b/json/perfect_float.patch deleted file mode 100644 index cf35977b..00000000 --- a/json/perfect_float.patch +++ /dev/null @@ -1,1669 +0,0 @@ -commit 62ef02bd14d2772c23915005700756dfafbe44d7 -Author: ijl -Date: Thu Apr 30 11:37:50 2020 +0000 - - Parse floats using simdjson, lexical - - This ports float parsing of simdjson for most floats and falls back - to lexical if needed. The simdjson code is from v0.3.1 and was - written by Daniel Lemire and John Keiser, 2019-2020, Apache 2.0. - -diff --git a/Cargo.toml b/Cargo.toml -index 9abde9d..028bc6a 100644 ---- a/Cargo.toml -+++ b/Cargo.toml -@@ -21,6 +21,7 @@ serde = { version = "1.0.100", default-features = false } - indexmap = { version = "1.2", optional = true } - itoa = { version = "0.4.3", default-features = false } - ryu = "1.0" -+lexical-core = { version = "0.7", default_features = false, features = ["correct", "format", "ryu"]} - - [dev-dependencies] - automod = "0.1" -diff --git a/src/de.rs b/src/de.rs -index 3aa8f29..33675cd 100644 ---- a/src/de.rs -+++ b/src/de.rs -@@ -382,6 +382,11 @@ impl<'de, R: Read<'de>> Deserializer { - } - - fn parse_integer(&mut self, positive: bool) -> Result { -+ let start = if positive { -+ self.read.byte_offset() -+ } else { -+ self.read.byte_offset() - 1 -+ }; - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { -@@ -394,7 +399,7 @@ impl<'de, R: Read<'de>> Deserializer { - // There can be only one leading '0'. - match tri!(self.peek_or_null()) { - b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), -- _ => self.parse_number(positive, 0), -+ _ => self.parse_number(positive, 0, start), - } - } - c @ b'1'..=b'9' => { -@@ -411,16 +416,15 @@ impl<'de, R: Read<'de>> Deserializer { - // parsing the value as a `f64`. - if overflow!(res * 10 + digit, u64::max_value()) { - return Ok(ParserNumber::F64(tri!(self.parse_long_integer( -- positive, -- res, -- 1, // res * 10^1 -+ positive, res, 1, // res * 10^1 -+ start, - )))); - } - - res = res * 10 + digit; - } - _ => { -- return self.parse_number(positive, res); -+ return self.parse_number(positive, res, start); - } - } - } -@@ -434,6 +438,7 @@ impl<'de, R: Read<'de>> Deserializer { - positive: bool, - significand: u64, - mut exponent: i32, -+ start: usize, - ) -> Result { - loop { - match tri!(self.peek_or_null()) { -@@ -444,22 +449,29 @@ impl<'de, R: Read<'de>> Deserializer { - exponent += 1; - } - b'.' => { -- return self.parse_decimal(positive, significand, exponent); -+ return self.parse_decimal(positive, significand, exponent, start); - } - b'e' | b'E' => { -- return self.parse_exponent(positive, significand, exponent); -+ return self.parse_exponent(positive, significand, exponent, start); - } - _ => { -- return self.f64_from_parts(positive, significand, exponent); -+ return self.f64_from_parts(positive, significand, exponent, start); - } - } - } - } - -- fn parse_number(&mut self, positive: bool, significand: u64) -> Result { -+ fn parse_number( -+ &mut self, -+ positive: bool, -+ significand: u64, -+ start: usize, -+ ) -> Result { - Ok(match tri!(self.peek_or_null()) { -- b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0))), -- b'e' | b'E' => ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0))), -+ b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0, start))), -+ b'e' | b'E' => { -+ ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0, start))) -+ } - _ => { - if positive { - ParserNumber::U64(significand) -@@ -482,6 +494,7 @@ impl<'de, R: Read<'de>> Deserializer { - positive: bool, - mut significand: u64, - mut exponent: i32, -+ start: usize, - ) -> Result { - self.eat_char(); - -@@ -512,8 +525,8 @@ impl<'de, R: Read<'de>> Deserializer { - } - - match tri!(self.peek_or_null()) { -- b'e' | b'E' => self.parse_exponent(positive, significand, exponent), -- _ => self.f64_from_parts(positive, significand, exponent), -+ b'e' | b'E' => self.parse_exponent(positive, significand, exponent, start), -+ _ => self.f64_from_parts(positive, significand, exponent, start), - } - } - -@@ -522,6 +535,7 @@ impl<'de, R: Read<'de>> Deserializer { - positive: bool, - significand: u64, - starting_exp: i32, -+ start: usize, - ) -> Result { - self.eat_char(); - -@@ -569,7 +583,7 @@ impl<'de, R: Read<'de>> Deserializer { - starting_exp.saturating_sub(exp) - }; - -- self.f64_from_parts(positive, significand, final_exp) -+ self.f64_from_parts(positive, significand, final_exp, start) - } - - // This cold code should not be inlined into the middle of the hot -@@ -747,35 +761,93 @@ impl<'de, R: Read<'de>> Deserializer { - &mut self, - positive: bool, - significand: u64, -- mut exponent: i32, -+ exponent: i32, -+ start: usize, - ) -> Result { -- let mut f = significand as f64; -- loop { -- match POW10.get(exponent.wrapping_abs() as usize) { -- Some(&pow) => { -- if exponent >= 0 { -- f *= pow; -- if f.is_infinite() { -- return Err(self.error(ErrorCode::NumberOutOfRange)); -- } -- } else { -- f /= pow; -- } -- break; -+ if -22 <= exponent && exponent <= 22 && significand <= 9007199254740991 { -+ let mut f = significand as f64; -+ if exponent < 0 { -+ f = f / POW10[-exponent as usize]; -+ } else { -+ f = f * POW10[exponent as usize]; -+ } -+ Ok(if positive { f } else { -f }) -+ } else if significand == 0 { -+ Ok(if positive { 0.0 } else { -0.0 }) -+ } else if exponent >= -325 && exponent <= 308 { -+ let (factor_mantissa, factor_exponent) = POW10_COMPONENTS[(exponent + 325) as usize]; -+ let mut leading_zeroes = significand.leading_zeros() as u64; -+ let f = significand << leading_zeroes; -+ let (mut lower, mut upper) = multiply_as_u128(f, factor_mantissa); -+ if upper & 0x1FF == 0x1FF && lower.wrapping_add(f) < lower { -+ let factor_mantissa_low = MANTISSA_128[(exponent + 325) as usize]; -+ let (product_low, product_middle2) = multiply_as_u128(f, factor_mantissa_low); -+ let product_middle1 = lower; -+ let mut product_high = upper; -+ let product_middle = product_middle1.wrapping_add(product_middle2); -+ if product_middle < product_middle1 { -+ product_high += 1; - } -- None => { -- if f == 0.0 { -- break; -- } -- if exponent >= 0 { -- return Err(self.error(ErrorCode::NumberOutOfRange)); -- } -- f /= 1e308; -- exponent += 308; -+ if product_middle.wrapping_add(1) == 0 -+ && product_high & 0x1FF == 0x1FF -+ && product_low.wrapping_add(f) < product_low -+ { -+ return self.f64_from_parts_slow(start); -+ } -+ upper = product_high; -+ lower = product_middle; -+ } -+ let upperbit = upper.wrapping_shr(63); -+ let mut mantissa = upper.wrapping_shr((upperbit + 9) as u32); -+ leading_zeroes += 1 ^ upperbit; -+ -+ if lower == 0 && upper & 0x1FF == 0 && mantissa & 3 == 1 { -+ return self.f64_from_parts_slow(start); -+ } -+ mantissa += mantissa & 1; -+ mantissa >>= 1; -+ -+ if mantissa >= 1 << 53 { -+ mantissa = 1 << 52; -+ leading_zeroes -= 1; -+ } -+ mantissa &= !(1 << 52); -+ let real_exponent = (factor_exponent as u64).wrapping_sub(leading_zeroes); -+ // we have to check that real_exponent is in range, otherwise we bail out -+ if real_exponent < 1 || real_exponent > 2046 { -+ return self.f64_from_parts_slow(start); -+ } -+ mantissa |= real_exponent.wrapping_shl(52); -+ mantissa |= (!positive as u64) << 63; -+ Ok(f64::from_bits(mantissa)) -+ } else { -+ self.f64_from_parts_slow(start) -+ } -+ } -+ -+ #[cold] -+ fn f64_from_parts_slow(&mut self, start: usize) -> Result { -+ let buf = self.read.slice_looking_back(start).unwrap(); -+ match lexical_core::parse_format::(buf, lexical_core::NumberFormat::JSON) { -+ Ok(val) => { -+ if val.is_infinite() { -+ Err(self.error(ErrorCode::NumberOutOfRange)) -+ } else { -+ Ok(val) - } - } -+ Err(err) => match err.code { -+ lexical_core::ErrorCode::ExponentWithoutFraction -+ | lexical_core::ErrorCode::MissingExponentSign -+ | lexical_core::ErrorCode::EmptyFraction -+ | lexical_core::ErrorCode::EmptyMantissa -+ | lexical_core::ErrorCode::EmptyExponent -+ | lexical_core::ErrorCode::MissingMantissaSign => { -+ Err(self.error(ErrorCode::EofWhileParsingValue)) -+ } -+ _ => Err(self.error(ErrorCode::InvalidNumber)), -+ }, - } -- Ok(if positive { f } else { -f }) - } - - fn parse_object_colon(&mut self) -> Result<()> { -@@ -1023,40 +1095,1288 @@ impl FromStr for Number { - } - } - --// Clippy bug: https://github.com/rust-lang/rust-clippy/issues/5201 --#[allow(clippy::excessive_precision)] --static POW10: [f64; 309] = [ -- 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, // -- 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019, // -- 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029, // -- 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039, // -- 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049, // -- 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059, // -- 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069, // -- 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079, // -- 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089, // -- 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099, // -- 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, // -- 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, // -- 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, // -- 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, // -- 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, // -- 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, // -- 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, // -- 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, // -- 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, // -- 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, // -- 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, // -- 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, // -- 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, // -- 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, // -- 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, // -- 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, // -- 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, // -- 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, // -- 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, // -- 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, // -- 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308, -+fn multiply_as_u128(a: u64, b: u64) -> (u64, u64) { -+ let res: u128 = a as u128 * b as u128; -+ (res as u64, (res >> 64) as u64) -+} -+ -+static POW10_COMPONENTS: [(u64, i32); 634] = [ -+ (0xa5ced43b7e3e9188, 7), -+ (0xcf42894a5dce35ea, 10), -+ (0x818995ce7aa0e1b2, 14), -+ (0xa1ebfb4219491a1f, 17), -+ (0xca66fa129f9b60a6, 20), -+ (0xfd00b897478238d0, 23), -+ (0x9e20735e8cb16382, 27), -+ (0xc5a890362fddbc62, 30), -+ (0xf712b443bbd52b7b, 33), -+ (0x9a6bb0aa55653b2d, 37), -+ (0xc1069cd4eabe89f8, 40), -+ (0xf148440a256e2c76, 43), -+ (0x96cd2a865764dbca, 47), -+ (0xbc807527ed3e12bc, 50), -+ (0xeba09271e88d976b, 53), -+ (0x93445b8731587ea3, 57), -+ (0xb8157268fdae9e4c, 60), -+ (0xe61acf033d1a45df, 63), -+ (0x8fd0c16206306bab, 67), -+ (0xb3c4f1ba87bc8696, 70), -+ (0xe0b62e2929aba83c, 73), -+ (0x8c71dcd9ba0b4925, 77), -+ (0xaf8e5410288e1b6f, 80), -+ (0xdb71e91432b1a24a, 83), -+ (0x892731ac9faf056e, 87), -+ (0xab70fe17c79ac6ca, 90), -+ (0xd64d3d9db981787d, 93), -+ (0x85f0468293f0eb4e, 97), -+ (0xa76c582338ed2621, 100), -+ (0xd1476e2c07286faa, 103), -+ (0x82cca4db847945ca, 107), -+ (0xa37fce126597973c, 110), -+ (0xcc5fc196fefd7d0c, 113), -+ (0xff77b1fcbebcdc4f, 116), -+ (0x9faacf3df73609b1, 120), -+ (0xc795830d75038c1d, 123), -+ (0xf97ae3d0d2446f25, 126), -+ (0x9becce62836ac577, 130), -+ (0xc2e801fb244576d5, 133), -+ (0xf3a20279ed56d48a, 136), -+ (0x9845418c345644d6, 140), -+ (0xbe5691ef416bd60c, 143), -+ (0xedec366b11c6cb8f, 146), -+ (0x94b3a202eb1c3f39, 150), -+ (0xb9e08a83a5e34f07, 153), -+ (0xe858ad248f5c22c9, 156), -+ (0x91376c36d99995be, 160), -+ (0xb58547448ffffb2d, 163), -+ (0xe2e69915b3fff9f9, 166), -+ (0x8dd01fad907ffc3b, 170), -+ (0xb1442798f49ffb4a, 173), -+ (0xdd95317f31c7fa1d, 176), -+ (0x8a7d3eef7f1cfc52, 180), -+ (0xad1c8eab5ee43b66, 183), -+ (0xd863b256369d4a40, 186), -+ (0x873e4f75e2224e68, 190), -+ (0xa90de3535aaae202, 193), -+ (0xd3515c2831559a83, 196), -+ (0x8412d9991ed58091, 200), -+ (0xa5178fff668ae0b6, 203), -+ (0xce5d73ff402d98e3, 206), -+ (0x80fa687f881c7f8e, 210), -+ (0xa139029f6a239f72, 213), -+ (0xc987434744ac874e, 216), -+ (0xfbe9141915d7a922, 219), -+ (0x9d71ac8fada6c9b5, 223), -+ (0xc4ce17b399107c22, 226), -+ (0xf6019da07f549b2b, 229), -+ (0x99c102844f94e0fb, 233), -+ (0xc0314325637a1939, 236), -+ (0xf03d93eebc589f88, 239), -+ (0x96267c7535b763b5, 243), -+ (0xbbb01b9283253ca2, 246), -+ (0xea9c227723ee8bcb, 249), -+ (0x92a1958a7675175f, 253), -+ (0xb749faed14125d36, 256), -+ (0xe51c79a85916f484, 259), -+ (0x8f31cc0937ae58d2, 263), -+ (0xb2fe3f0b8599ef07, 266), -+ (0xdfbdcece67006ac9, 269), -+ (0x8bd6a141006042bd, 273), -+ (0xaecc49914078536d, 276), -+ (0xda7f5bf590966848, 279), -+ (0x888f99797a5e012d, 283), -+ (0xaab37fd7d8f58178, 286), -+ (0xd5605fcdcf32e1d6, 289), -+ (0x855c3be0a17fcd26, 293), -+ (0xa6b34ad8c9dfc06f, 296), -+ (0xd0601d8efc57b08b, 299), -+ (0x823c12795db6ce57, 303), -+ (0xa2cb1717b52481ed, 306), -+ (0xcb7ddcdda26da268, 309), -+ (0xfe5d54150b090b02, 312), -+ (0x9efa548d26e5a6e1, 316), -+ (0xc6b8e9b0709f109a, 319), -+ (0xf867241c8cc6d4c0, 322), -+ (0x9b407691d7fc44f8, 326), -+ (0xc21094364dfb5636, 329), -+ (0xf294b943e17a2bc4, 332), -+ (0x979cf3ca6cec5b5a, 336), -+ (0xbd8430bd08277231, 339), -+ (0xece53cec4a314ebd, 342), -+ (0x940f4613ae5ed136, 346), -+ (0xb913179899f68584, 349), -+ (0xe757dd7ec07426e5, 352), -+ (0x9096ea6f3848984f, 356), -+ (0xb4bca50b065abe63, 359), -+ (0xe1ebce4dc7f16dfb, 362), -+ (0x8d3360f09cf6e4bd, 366), -+ (0xb080392cc4349dec, 369), -+ (0xdca04777f541c567, 372), -+ (0x89e42caaf9491b60, 376), -+ (0xac5d37d5b79b6239, 379), -+ (0xd77485cb25823ac7, 382), -+ (0x86a8d39ef77164bc, 386), -+ (0xa8530886b54dbdeb, 389), -+ (0xd267caa862a12d66, 392), -+ (0x8380dea93da4bc60, 396), -+ (0xa46116538d0deb78, 399), -+ (0xcd795be870516656, 402), -+ (0x806bd9714632dff6, 406), -+ (0xa086cfcd97bf97f3, 409), -+ (0xc8a883c0fdaf7df0, 412), -+ (0xfad2a4b13d1b5d6c, 415), -+ (0x9cc3a6eec6311a63, 419), -+ (0xc3f490aa77bd60fc, 422), -+ (0xf4f1b4d515acb93b, 425), -+ (0x991711052d8bf3c5, 429), -+ (0xbf5cd54678eef0b6, 432), -+ (0xef340a98172aace4, 435), -+ (0x9580869f0e7aac0e, 439), -+ (0xbae0a846d2195712, 442), -+ (0xe998d258869facd7, 445), -+ (0x91ff83775423cc06, 449), -+ (0xb67f6455292cbf08, 452), -+ (0xe41f3d6a7377eeca, 455), -+ (0x8e938662882af53e, 459), -+ (0xb23867fb2a35b28d, 462), -+ (0xdec681f9f4c31f31, 465), -+ (0x8b3c113c38f9f37e, 469), -+ (0xae0b158b4738705e, 472), -+ (0xd98ddaee19068c76, 475), -+ (0x87f8a8d4cfa417c9, 479), -+ (0xa9f6d30a038d1dbc, 482), -+ (0xd47487cc8470652b, 485), -+ (0x84c8d4dfd2c63f3b, 489), -+ (0xa5fb0a17c777cf09, 492), -+ (0xcf79cc9db955c2cc, 495), -+ (0x81ac1fe293d599bf, 499), -+ (0xa21727db38cb002f, 502), -+ (0xca9cf1d206fdc03b, 505), -+ (0xfd442e4688bd304a, 508), -+ (0x9e4a9cec15763e2e, 512), -+ (0xc5dd44271ad3cdba, 515), -+ (0xf7549530e188c128, 518), -+ (0x9a94dd3e8cf578b9, 522), -+ (0xc13a148e3032d6e7, 525), -+ (0xf18899b1bc3f8ca1, 528), -+ (0x96f5600f15a7b7e5, 532), -+ (0xbcb2b812db11a5de, 535), -+ (0xebdf661791d60f56, 538), -+ (0x936b9fcebb25c995, 542), -+ (0xb84687c269ef3bfb, 545), -+ (0xe65829b3046b0afa, 548), -+ (0x8ff71a0fe2c2e6dc, 552), -+ (0xb3f4e093db73a093, 555), -+ (0xe0f218b8d25088b8, 558), -+ (0x8c974f7383725573, 562), -+ (0xafbd2350644eeacf, 565), -+ (0xdbac6c247d62a583, 568), -+ (0x894bc396ce5da772, 572), -+ (0xab9eb47c81f5114f, 575), -+ (0xd686619ba27255a2, 578), -+ (0x8613fd0145877585, 582), -+ (0xa798fc4196e952e7, 585), -+ (0xd17f3b51fca3a7a0, 588), -+ (0x82ef85133de648c4, 592), -+ (0xa3ab66580d5fdaf5, 595), -+ (0xcc963fee10b7d1b3, 598), -+ (0xffbbcfe994e5c61f, 601), -+ (0x9fd561f1fd0f9bd3, 605), -+ (0xc7caba6e7c5382c8, 608), -+ (0xf9bd690a1b68637b, 611), -+ (0x9c1661a651213e2d, 615), -+ (0xc31bfa0fe5698db8, 618), -+ (0xf3e2f893dec3f126, 621), -+ (0x986ddb5c6b3a76b7, 625), -+ (0xbe89523386091465, 628), -+ (0xee2ba6c0678b597f, 631), -+ (0x94db483840b717ef, 635), -+ (0xba121a4650e4ddeb, 638), -+ (0xe896a0d7e51e1566, 641), -+ (0x915e2486ef32cd60, 645), -+ (0xb5b5ada8aaff80b8, 648), -+ (0xe3231912d5bf60e6, 651), -+ (0x8df5efabc5979c8f, 655), -+ (0xb1736b96b6fd83b3, 658), -+ (0xddd0467c64bce4a0, 661), -+ (0x8aa22c0dbef60ee4, 665), -+ (0xad4ab7112eb3929d, 668), -+ (0xd89d64d57a607744, 671), -+ (0x87625f056c7c4a8b, 675), -+ (0xa93af6c6c79b5d2d, 678), -+ (0xd389b47879823479, 681), -+ (0x843610cb4bf160cb, 685), -+ (0xa54394fe1eedb8fe, 688), -+ (0xce947a3da6a9273e, 691), -+ (0x811ccc668829b887, 695), -+ (0xa163ff802a3426a8, 698), -+ (0xc9bcff6034c13052, 701), -+ (0xfc2c3f3841f17c67, 704), -+ (0x9d9ba7832936edc0, 708), -+ (0xc5029163f384a931, 711), -+ (0xf64335bcf065d37d, 714), -+ (0x99ea0196163fa42e, 718), -+ (0xc06481fb9bcf8d39, 721), -+ (0xf07da27a82c37088, 724), -+ (0x964e858c91ba2655, 728), -+ (0xbbe226efb628afea, 731), -+ (0xeadab0aba3b2dbe5, 734), -+ (0x92c8ae6b464fc96f, 738), -+ (0xb77ada0617e3bbcb, 741), -+ (0xe55990879ddcaabd, 744), -+ (0x8f57fa54c2a9eab6, 748), -+ (0xb32df8e9f3546564, 751), -+ (0xdff9772470297ebd, 754), -+ (0x8bfbea76c619ef36, 758), -+ (0xaefae51477a06b03, 761), -+ (0xdab99e59958885c4, 764), -+ (0x88b402f7fd75539b, 768), -+ (0xaae103b5fcd2a881, 771), -+ (0xd59944a37c0752a2, 774), -+ (0x857fcae62d8493a5, 778), -+ (0xa6dfbd9fb8e5b88e, 781), -+ (0xd097ad07a71f26b2, 784), -+ (0x825ecc24c873782f, 788), -+ (0xa2f67f2dfa90563b, 791), -+ (0xcbb41ef979346bca, 794), -+ (0xfea126b7d78186bc, 797), -+ (0x9f24b832e6b0f436, 801), -+ (0xc6ede63fa05d3143, 804), -+ (0xf8a95fcf88747d94, 807), -+ (0x9b69dbe1b548ce7c, 811), -+ (0xc24452da229b021b, 814), -+ (0xf2d56790ab41c2a2, 817), -+ (0x97c560ba6b0919a5, 821), -+ (0xbdb6b8e905cb600f, 824), -+ (0xed246723473e3813, 827), -+ (0x9436c0760c86e30b, 831), -+ (0xb94470938fa89bce, 834), -+ (0xe7958cb87392c2c2, 837), -+ (0x90bd77f3483bb9b9, 841), -+ (0xb4ecd5f01a4aa828, 844), -+ (0xe2280b6c20dd5232, 847), -+ (0x8d590723948a535f, 851), -+ (0xb0af48ec79ace837, 854), -+ (0xdcdb1b2798182244, 857), -+ (0x8a08f0f8bf0f156b, 861), -+ (0xac8b2d36eed2dac5, 864), -+ (0xd7adf884aa879177, 867), -+ (0x86ccbb52ea94baea, 871), -+ (0xa87fea27a539e9a5, 874), -+ (0xd29fe4b18e88640e, 877), -+ (0x83a3eeeef9153e89, 881), -+ (0xa48ceaaab75a8e2b, 884), -+ (0xcdb02555653131b6, 887), -+ (0x808e17555f3ebf11, 891), -+ (0xa0b19d2ab70e6ed6, 894), -+ (0xc8de047564d20a8b, 897), -+ (0xfb158592be068d2e, 900), -+ (0x9ced737bb6c4183d, 904), -+ (0xc428d05aa4751e4c, 907), -+ (0xf53304714d9265df, 910), -+ (0x993fe2c6d07b7fab, 914), -+ (0xbf8fdb78849a5f96, 917), -+ (0xef73d256a5c0f77c, 920), -+ (0x95a8637627989aad, 924), -+ (0xbb127c53b17ec159, 927), -+ (0xe9d71b689dde71af, 930), -+ (0x9226712162ab070d, 934), -+ (0xb6b00d69bb55c8d1, 937), -+ (0xe45c10c42a2b3b05, 940), -+ (0x8eb98a7a9a5b04e3, 944), -+ (0xb267ed1940f1c61c, 947), -+ (0xdf01e85f912e37a3, 950), -+ (0x8b61313bbabce2c6, 954), -+ (0xae397d8aa96c1b77, 957), -+ (0xd9c7dced53c72255, 960), -+ (0x881cea14545c7575, 964), -+ (0xaa242499697392d2, 967), -+ (0xd4ad2dbfc3d07787, 970), -+ (0x84ec3c97da624ab4, 974), -+ (0xa6274bbdd0fadd61, 977), -+ (0xcfb11ead453994ba, 980), -+ (0x81ceb32c4b43fcf4, 984), -+ (0xa2425ff75e14fc31, 987), -+ (0xcad2f7f5359a3b3e, 990), -+ (0xfd87b5f28300ca0d, 993), -+ (0x9e74d1b791e07e48, 997), -+ (0xc612062576589dda, 1000), -+ (0xf79687aed3eec551, 1003), -+ (0x9abe14cd44753b52, 1007), -+ (0xc16d9a0095928a27, 1010), -+ (0xf1c90080baf72cb1, 1013), -+ (0x971da05074da7bee, 1017), -+ (0xbce5086492111aea, 1020), -+ (0xec1e4a7db69561a5, 1023), -+ (0x9392ee8e921d5d07, 1027), -+ (0xb877aa3236a4b449, 1030), -+ (0xe69594bec44de15b, 1033), -+ (0x901d7cf73ab0acd9, 1037), -+ (0xb424dc35095cd80f, 1040), -+ (0xe12e13424bb40e13, 1043), -+ (0x8cbccc096f5088cb, 1047), -+ (0xafebff0bcb24aafe, 1050), -+ (0xdbe6fecebdedd5be, 1053), -+ (0x89705f4136b4a597, 1057), -+ (0xabcc77118461cefc, 1060), -+ (0xd6bf94d5e57a42bc, 1063), -+ (0x8637bd05af6c69b5, 1067), -+ (0xa7c5ac471b478423, 1070), -+ (0xd1b71758e219652b, 1073), -+ (0x83126e978d4fdf3b, 1077), -+ (0xa3d70a3d70a3d70a, 1080), -+ (0xcccccccccccccccc, 1083), -+ (0x8000000000000000, 1087), -+ (0xa000000000000000, 1090), -+ (0xc800000000000000, 1093), -+ (0xfa00000000000000, 1096), -+ (0x9c40000000000000, 1100), -+ (0xc350000000000000, 1103), -+ (0xf424000000000000, 1106), -+ (0x9896800000000000, 1110), -+ (0xbebc200000000000, 1113), -+ (0xee6b280000000000, 1116), -+ (0x9502f90000000000, 1120), -+ (0xba43b74000000000, 1123), -+ (0xe8d4a51000000000, 1126), -+ (0x9184e72a00000000, 1130), -+ (0xb5e620f480000000, 1133), -+ (0xe35fa931a0000000, 1136), -+ (0x8e1bc9bf04000000, 1140), -+ (0xb1a2bc2ec5000000, 1143), -+ (0xde0b6b3a76400000, 1146), -+ (0x8ac7230489e80000, 1150), -+ (0xad78ebc5ac620000, 1153), -+ (0xd8d726b7177a8000, 1156), -+ (0x878678326eac9000, 1160), -+ (0xa968163f0a57b400, 1163), -+ (0xd3c21bcecceda100, 1166), -+ (0x84595161401484a0, 1170), -+ (0xa56fa5b99019a5c8, 1173), -+ (0xcecb8f27f4200f3a, 1176), -+ (0x813f3978f8940984, 1180), -+ (0xa18f07d736b90be5, 1183), -+ (0xc9f2c9cd04674ede, 1186), -+ (0xfc6f7c4045812296, 1189), -+ (0x9dc5ada82b70b59d, 1193), -+ (0xc5371912364ce305, 1196), -+ (0xf684df56c3e01bc6, 1199), -+ (0x9a130b963a6c115c, 1203), -+ (0xc097ce7bc90715b3, 1206), -+ (0xf0bdc21abb48db20, 1209), -+ (0x96769950b50d88f4, 1213), -+ (0xbc143fa4e250eb31, 1216), -+ (0xeb194f8e1ae525fd, 1219), -+ (0x92efd1b8d0cf37be, 1223), -+ (0xb7abc627050305ad, 1226), -+ (0xe596b7b0c643c719, 1229), -+ (0x8f7e32ce7bea5c6f, 1233), -+ (0xb35dbf821ae4f38b, 1236), -+ (0xe0352f62a19e306e, 1239), -+ (0x8c213d9da502de45, 1243), -+ (0xaf298d050e4395d6, 1246), -+ (0xdaf3f04651d47b4c, 1249), -+ (0x88d8762bf324cd0f, 1253), -+ (0xab0e93b6efee0053, 1256), -+ (0xd5d238a4abe98068, 1259), -+ (0x85a36366eb71f041, 1263), -+ (0xa70c3c40a64e6c51, 1266), -+ (0xd0cf4b50cfe20765, 1269), -+ (0x82818f1281ed449f, 1273), -+ (0xa321f2d7226895c7, 1276), -+ (0xcbea6f8ceb02bb39, 1279), -+ (0xfee50b7025c36a08, 1282), -+ (0x9f4f2726179a2245, 1286), -+ (0xc722f0ef9d80aad6, 1289), -+ (0xf8ebad2b84e0d58b, 1292), -+ (0x9b934c3b330c8577, 1296), -+ (0xc2781f49ffcfa6d5, 1299), -+ (0xf316271c7fc3908a, 1302), -+ (0x97edd871cfda3a56, 1306), -+ (0xbde94e8e43d0c8ec, 1309), -+ (0xed63a231d4c4fb27, 1312), -+ (0x945e455f24fb1cf8, 1316), -+ (0xb975d6b6ee39e436, 1319), -+ (0xe7d34c64a9c85d44, 1322), -+ (0x90e40fbeea1d3a4a, 1326), -+ (0xb51d13aea4a488dd, 1329), -+ (0xe264589a4dcdab14, 1332), -+ (0x8d7eb76070a08aec, 1336), -+ (0xb0de65388cc8ada8, 1339), -+ (0xdd15fe86affad912, 1342), -+ (0x8a2dbf142dfcc7ab, 1346), -+ (0xacb92ed9397bf996, 1349), -+ (0xd7e77a8f87daf7fb, 1352), -+ (0x86f0ac99b4e8dafd, 1356), -+ (0xa8acd7c0222311bc, 1359), -+ (0xd2d80db02aabd62b, 1362), -+ (0x83c7088e1aab65db, 1366), -+ (0xa4b8cab1a1563f52, 1369), -+ (0xcde6fd5e09abcf26, 1372), -+ (0x80b05e5ac60b6178, 1376), -+ (0xa0dc75f1778e39d6, 1379), -+ (0xc913936dd571c84c, 1382), -+ (0xfb5878494ace3a5f, 1385), -+ (0x9d174b2dcec0e47b, 1389), -+ (0xc45d1df942711d9a, 1392), -+ (0xf5746577930d6500, 1395), -+ (0x9968bf6abbe85f20, 1399), -+ (0xbfc2ef456ae276e8, 1402), -+ (0xefb3ab16c59b14a2, 1405), -+ (0x95d04aee3b80ece5, 1409), -+ (0xbb445da9ca61281f, 1412), -+ (0xea1575143cf97226, 1415), -+ (0x924d692ca61be758, 1419), -+ (0xb6e0c377cfa2e12e, 1422), -+ (0xe498f455c38b997a, 1425), -+ (0x8edf98b59a373fec, 1429), -+ (0xb2977ee300c50fe7, 1432), -+ (0xdf3d5e9bc0f653e1, 1435), -+ (0x8b865b215899f46c, 1439), -+ (0xae67f1e9aec07187, 1442), -+ (0xda01ee641a708de9, 1445), -+ (0x884134fe908658b2, 1449), -+ (0xaa51823e34a7eede, 1452), -+ (0xd4e5e2cdc1d1ea96, 1455), -+ (0x850fadc09923329e, 1459), -+ (0xa6539930bf6bff45, 1462), -+ (0xcfe87f7cef46ff16, 1465), -+ (0x81f14fae158c5f6e, 1469), -+ (0xa26da3999aef7749, 1472), -+ (0xcb090c8001ab551c, 1475), -+ (0xfdcb4fa002162a63, 1478), -+ (0x9e9f11c4014dda7e, 1482), -+ (0xc646d63501a1511d, 1485), -+ (0xf7d88bc24209a565, 1488), -+ (0x9ae757596946075f, 1492), -+ (0xc1a12d2fc3978937, 1495), -+ (0xf209787bb47d6b84, 1498), -+ (0x9745eb4d50ce6332, 1502), -+ (0xbd176620a501fbff, 1505), -+ (0xec5d3fa8ce427aff, 1508), -+ (0x93ba47c980e98cdf, 1512), -+ (0xb8a8d9bbe123f017, 1515), -+ (0xe6d3102ad96cec1d, 1518), -+ (0x9043ea1ac7e41392, 1522), -+ (0xb454e4a179dd1877, 1525), -+ (0xe16a1dc9d8545e94, 1528), -+ (0x8ce2529e2734bb1d, 1532), -+ (0xb01ae745b101e9e4, 1535), -+ (0xdc21a1171d42645d, 1538), -+ (0x899504ae72497eba, 1542), -+ (0xabfa45da0edbde69, 1545), -+ (0xd6f8d7509292d603, 1548), -+ (0x865b86925b9bc5c2, 1552), -+ (0xa7f26836f282b732, 1555), -+ (0xd1ef0244af2364ff, 1558), -+ (0x8335616aed761f1f, 1562), -+ (0xa402b9c5a8d3a6e7, 1565), -+ (0xcd036837130890a1, 1568), -+ (0x802221226be55a64, 1572), -+ (0xa02aa96b06deb0fd, 1575), -+ (0xc83553c5c8965d3d, 1578), -+ (0xfa42a8b73abbf48c, 1581), -+ (0x9c69a97284b578d7, 1585), -+ (0xc38413cf25e2d70d, 1588), -+ (0xf46518c2ef5b8cd1, 1591), -+ (0x98bf2f79d5993802, 1595), -+ (0xbeeefb584aff8603, 1598), -+ (0xeeaaba2e5dbf6784, 1601), -+ (0x952ab45cfa97a0b2, 1605), -+ (0xba756174393d88df, 1608), -+ (0xe912b9d1478ceb17, 1611), -+ (0x91abb422ccb812ee, 1615), -+ (0xb616a12b7fe617aa, 1618), -+ (0xe39c49765fdf9d94, 1621), -+ (0x8e41ade9fbebc27d, 1625), -+ (0xb1d219647ae6b31c, 1628), -+ (0xde469fbd99a05fe3, 1631), -+ (0x8aec23d680043bee, 1635), -+ (0xada72ccc20054ae9, 1638), -+ (0xd910f7ff28069da4, 1641), -+ (0x87aa9aff79042286, 1645), -+ (0xa99541bf57452b28, 1648), -+ (0xd3fa922f2d1675f2, 1651), -+ (0x847c9b5d7c2e09b7, 1655), -+ (0xa59bc234db398c25, 1658), -+ (0xcf02b2c21207ef2e, 1661), -+ (0x8161afb94b44f57d, 1665), -+ (0xa1ba1ba79e1632dc, 1668), -+ (0xca28a291859bbf93, 1671), -+ (0xfcb2cb35e702af78, 1674), -+ (0x9defbf01b061adab, 1678), -+ (0xc56baec21c7a1916, 1681), -+ (0xf6c69a72a3989f5b, 1684), -+ (0x9a3c2087a63f6399, 1688), -+ (0xc0cb28a98fcf3c7f, 1691), -+ (0xf0fdf2d3f3c30b9f, 1694), -+ (0x969eb7c47859e743, 1698), -+ (0xbc4665b596706114, 1701), -+ (0xeb57ff22fc0c7959, 1704), -+ (0x9316ff75dd87cbd8, 1708), -+ (0xb7dcbf5354e9bece, 1711), -+ (0xe5d3ef282a242e81, 1714), -+ (0x8fa475791a569d10, 1718), -+ (0xb38d92d760ec4455, 1721), -+ (0xe070f78d3927556a, 1724), -+ (0x8c469ab843b89562, 1728), -+ (0xaf58416654a6babb, 1731), -+ (0xdb2e51bfe9d0696a, 1734), -+ (0x88fcf317f22241e2, 1738), -+ (0xab3c2fddeeaad25a, 1741), -+ (0xd60b3bd56a5586f1, 1744), -+ (0x85c7056562757456, 1748), -+ (0xa738c6bebb12d16c, 1751), -+ (0xd106f86e69d785c7, 1754), -+ (0x82a45b450226b39c, 1758), -+ (0xa34d721642b06084, 1761), -+ (0xcc20ce9bd35c78a5, 1764), -+ (0xff290242c83396ce, 1767), -+ (0x9f79a169bd203e41, 1771), -+ (0xc75809c42c684dd1, 1774), -+ (0xf92e0c3537826145, 1777), -+ (0x9bbcc7a142b17ccb, 1781), -+ (0xc2abf989935ddbfe, 1784), -+ (0xf356f7ebf83552fe, 1787), -+ (0x98165af37b2153de, 1791), -+ (0xbe1bf1b059e9a8d6, 1794), -+ (0xeda2ee1c7064130c, 1797), -+ (0x9485d4d1c63e8be7, 1801), -+ (0xb9a74a0637ce2ee1, 1804), -+ (0xe8111c87c5c1ba99, 1807), -+ (0x910ab1d4db9914a0, 1811), -+ (0xb54d5e4a127f59c8, 1814), -+ (0xe2a0b5dc971f303a, 1817), -+ (0x8da471a9de737e24, 1821), -+ (0xb10d8e1456105dad, 1824), -+ (0xdd50f1996b947518, 1827), -+ (0x8a5296ffe33cc92f, 1831), -+ (0xace73cbfdc0bfb7b, 1834), -+ (0xd8210befd30efa5a, 1837), -+ (0x8714a775e3e95c78, 1841), -+ (0xa8d9d1535ce3b396, 1844), -+ (0xd31045a8341ca07c, 1847), -+ (0x83ea2b892091e44d, 1851), -+ (0xa4e4b66b68b65d60, 1854), -+ (0xce1de40642e3f4b9, 1857), -+ (0x80d2ae83e9ce78f3, 1861), -+ (0xa1075a24e4421730, 1864), -+ (0xc94930ae1d529cfc, 1867), -+ (0xfb9b7cd9a4a7443c, 1870), -+ (0x9d412e0806e88aa5, 1874), -+ (0xc491798a08a2ad4e, 1877), -+ (0xf5b5d7ec8acb58a2, 1880), -+ (0x9991a6f3d6bf1765, 1884), -+ (0xbff610b0cc6edd3f, 1887), -+ (0xeff394dcff8a948e, 1890), -+ (0x95f83d0a1fb69cd9, 1894), -+ (0xbb764c4ca7a4440f, 1897), -+ (0xea53df5fd18d5513, 1900), -+ (0x92746b9be2f8552c, 1904), -+ (0xb7118682dbb66a77, 1907), -+ (0xe4d5e82392a40515, 1910), -+ (0x8f05b1163ba6832d, 1914), -+ (0xb2c71d5bca9023f8, 1917), -+ (0xdf78e4b2bd342cf6, 1920), -+ (0x8bab8eefb6409c1a, 1924), -+ (0xae9672aba3d0c320, 1927), -+ (0xda3c0f568cc4f3e8, 1930), -+ (0x8865899617fb1871, 1934), -+ (0xaa7eebfb9df9de8d, 1937), -+ (0xd51ea6fa85785631, 1940), -+ (0x8533285c936b35de, 1944), -+ (0xa67ff273b8460356, 1947), -+ (0xd01fef10a657842c, 1950), -+ (0x8213f56a67f6b29b, 1954), -+ (0xa298f2c501f45f42, 1957), -+ (0xcb3f2f7642717713, 1960), -+ (0xfe0efb53d30dd4d7, 1963), -+ (0x9ec95d1463e8a506, 1967), -+ (0xc67bb4597ce2ce48, 1970), -+ (0xf81aa16fdc1b81da, 1973), -+ (0x9b10a4e5e9913128, 1977), -+ (0xc1d4ce1f63f57d72, 1980), -+ (0xf24a01a73cf2dccf, 1983), -+ (0x976e41088617ca01, 1987), -+ (0xbd49d14aa79dbc82, 1990), -+ (0xec9c459d51852ba2, 1993), -+ (0x93e1ab8252f33b45, 1997), -+ (0xb8da1662e7b00a17, 2000), -+ (0xe7109bfba19c0c9d, 2003), -+ (0x906a617d450187e2, 2007), -+ (0xb484f9dc9641e9da, 2010), -+ (0xe1a63853bbd26451, 2013), -+ (0x8d07e33455637eb2, 2017), -+ (0xb049dc016abc5e5f, 2020), -+ (0xdc5c5301c56b75f7, 2023), -+ (0x89b9b3e11b6329ba, 2027), -+ (0xac2820d9623bf429, 2030), -+ (0xd732290fbacaf133, 2033), -+ (0x867f59a9d4bed6c0, 2037), -+ (0xa81f301449ee8c70, 2040), -+ (0xd226fc195c6a2f8c, 2043), -+ (0x83585d8fd9c25db7, 2047), -+ (0xa42e74f3d032f525, 2050), -+ (0xcd3a1230c43fb26f, 2053), -+ (0x80444b5e7aa7cf85, 2057), -+ (0xa0555e361951c366, 2060), -+ (0xc86ab5c39fa63440, 2063), -+ (0xfa856334878fc150, 2066), -+ (0x9c935e00d4b9d8d2, 2070), -+ (0xc3b8358109e84f07, 2073), -+ (0xf4a642e14c6262c8, 2076), -+ (0x98e7e9cccfbd7dbd, 2080), -+ (0xbf21e44003acdd2c, 2083), -+ (0xeeea5d5004981478, 2086), -+ (0x95527a5202df0ccb, 2090), -+ (0xbaa718e68396cffd, 2093), -+ (0xe950df20247c83fd, 2096), -+ (0x91d28b7416cdd27e, 2100), -+ (0xb6472e511c81471d, 2103), -+ (0xe3d8f9e563a198e5, 2106), -+ (0x8e679c2f5e44ff8f, 2110), -+]; -+ -+const MANTISSA_128: [u64; 634] = [ -+ 0x419ea3bd35385e2d, -+ 0x52064cac828675b9, -+ 0x7343efebd1940993, -+ 0x1014ebe6c5f90bf8, -+ 0xd41a26e077774ef6, -+ 0x8920b098955522b4, -+ 0x55b46e5f5d5535b0, -+ 0xeb2189f734aa831d, -+ 0xa5e9ec7501d523e4, -+ 0x47b233c92125366e, -+ 0x999ec0bb696e840a, -+ 0xc00670ea43ca250d, -+ 0x380406926a5e5728, -+ 0xc605083704f5ecf2, -+ 0xf7864a44c633682e, -+ 0x7ab3ee6afbe0211d, -+ 0x5960ea05bad82964, -+ 0x6fb92487298e33bd, -+ 0xa5d3b6d479f8e056, -+ 0x8f48a4899877186c, -+ 0x331acdabfe94de87, -+ 0x9ff0c08b7f1d0b14, -+ 0x7ecf0ae5ee44dd9, -+ 0xc9e82cd9f69d6150, -+ 0xbe311c083a225cd2, -+ 0x6dbd630a48aaf406, -+ 0x92cbbccdad5b108, -+ 0x25bbf56008c58ea5, -+ 0xaf2af2b80af6f24e, -+ 0x1af5af660db4aee1, -+ 0x50d98d9fc890ed4d, -+ 0xe50ff107bab528a0, -+ 0x1e53ed49a96272c8, -+ 0x25e8e89c13bb0f7a, -+ 0x77b191618c54e9ac, -+ 0xd59df5b9ef6a2417, -+ 0x4b0573286b44ad1d, -+ 0x4ee367f9430aec32, -+ 0x229c41f793cda73f, -+ 0x6b43527578c1110f, -+ 0x830a13896b78aaa9, -+ 0x23cc986bc656d553, -+ 0x2cbfbe86b7ec8aa8, -+ 0x7bf7d71432f3d6a9, -+ 0xdaf5ccd93fb0cc53, -+ 0xd1b3400f8f9cff68, -+ 0x23100809b9c21fa1, -+ 0xabd40a0c2832a78a, -+ 0x16c90c8f323f516c, -+ 0xae3da7d97f6792e3, -+ 0x99cd11cfdf41779c, -+ 0x40405643d711d583, -+ 0x482835ea666b2572, -+ 0xda3243650005eecf, -+ 0x90bed43e40076a82, -+ 0x5a7744a6e804a291, -+ 0x711515d0a205cb36, -+ 0xd5a5b44ca873e03, -+ 0xe858790afe9486c2, -+ 0x626e974dbe39a872, -+ 0xfb0a3d212dc8128f, -+ 0x7ce66634bc9d0b99, -+ 0x1c1fffc1ebc44e80, -+ 0xa327ffb266b56220, -+ 0x4bf1ff9f0062baa8, -+ 0x6f773fc3603db4a9, -+ 0xcb550fb4384d21d3, -+ 0x7e2a53a146606a48, -+ 0x2eda7444cbfc426d, -+ 0xfa911155fefb5308, -+ 0x793555ab7eba27ca, -+ 0x4bc1558b2f3458de, -+ 0x9eb1aaedfb016f16, -+ 0x465e15a979c1cadc, -+ 0xbfacd89ec191ec9, -+ 0xcef980ec671f667b, -+ 0x82b7e12780e7401a, -+ 0xd1b2ecb8b0908810, -+ 0x861fa7e6dcb4aa15, -+ 0x67a791e093e1d49a, -+ 0xe0c8bb2c5c6d24e0, -+ 0x58fae9f773886e18, -+ 0xaf39a475506a899e, -+ 0x6d8406c952429603, -+ 0xc8e5087ba6d33b83, -+ 0xfb1e4a9a90880a64, -+ 0x5cf2eea09a55067f, -+ 0xf42faa48c0ea481e, -+ 0xf13b94daf124da26, -+ 0x76c53d08d6b70858, -+ 0x54768c4b0c64ca6e, -+ 0xa9942f5dcf7dfd09, -+ 0xd3f93b35435d7c4c, -+ 0xc47bc5014a1a6daf, -+ 0x359ab6419ca1091b, -+ 0xc30163d203c94b62, -+ 0x79e0de63425dcf1d, -+ 0x985915fc12f542e4, -+ 0x3e6f5b7b17b2939d, -+ 0xa705992ceecf9c42, -+ 0x50c6ff782a838353, -+ 0xa4f8bf5635246428, -+ 0x871b7795e136be99, -+ 0x28e2557b59846e3f, -+ 0x331aeada2fe589cf, -+ 0x3ff0d2c85def7621, -+ 0xfed077a756b53a9, -+ 0xd3e8495912c62894, -+ 0x64712dd7abbbd95c, -+ 0xbd8d794d96aacfb3, -+ 0xecf0d7a0fc5583a0, -+ 0xf41686c49db57244, -+ 0x311c2875c522ced5, -+ 0x7d633293366b828b, -+ 0xae5dff9c02033197, -+ 0xd9f57f830283fdfc, -+ 0xd072df63c324fd7b, -+ 0x4247cb9e59f71e6d, -+ 0x52d9be85f074e608, -+ 0x67902e276c921f8b, -+ 0xba1cd8a3db53b6, -+ 0x80e8a40eccd228a4, -+ 0x6122cd128006b2cd, -+ 0x796b805720085f81, -+ 0xcbe3303674053bb0, -+ 0xbedbfc4411068a9c, -+ 0xee92fb5515482d44, -+ 0x751bdd152d4d1c4a, -+ 0xd262d45a78a0635d, -+ 0x86fb897116c87c34, -+ 0xd45d35e6ae3d4da0, -+ 0x8974836059cca109, -+ 0x2bd1a438703fc94b, -+ 0x7b6306a34627ddcf, -+ 0x1a3bc84c17b1d542, -+ 0x20caba5f1d9e4a93, -+ 0x547eb47b7282ee9c, -+ 0xe99e619a4f23aa43, -+ 0x6405fa00e2ec94d4, -+ 0xde83bc408dd3dd04, -+ 0x9624ab50b148d445, -+ 0x3badd624dd9b0957, -+ 0xe54ca5d70a80e5d6, -+ 0x5e9fcf4ccd211f4c, -+ 0x7647c3200069671f, -+ 0x29ecd9f40041e073, -+ 0xf468107100525890, -+ 0x7182148d4066eeb4, -+ 0xc6f14cd848405530, -+ 0xb8ada00e5a506a7c, -+ 0xa6d90811f0e4851c, -+ 0x908f4a166d1da663, -+ 0x9a598e4e043287fe, -+ 0x40eff1e1853f29fd, -+ 0xd12bee59e68ef47c, -+ 0x82bb74f8301958ce, -+ 0xe36a52363c1faf01, -+ 0xdc44e6c3cb279ac1, -+ 0x29ab103a5ef8c0b9, -+ 0x7415d448f6b6f0e7, -+ 0x111b495b3464ad21, -+ 0xcab10dd900beec34, -+ 0x3d5d514f40eea742, -+ 0xcb4a5a3112a5112, -+ 0x47f0e785eaba72ab, -+ 0x59ed216765690f56, -+ 0x306869c13ec3532c, -+ 0x1e414218c73a13fb, -+ 0xe5d1929ef90898fa, -+ 0xdf45f746b74abf39, -+ 0x6b8bba8c328eb783, -+ 0x66ea92f3f326564, -+ 0xc80a537b0efefebd, -+ 0xbd06742ce95f5f36, -+ 0x2c48113823b73704, -+ 0xf75a15862ca504c5, -+ 0x9a984d73dbe722fb, -+ 0xc13e60d0d2e0ebba, -+ 0x318df905079926a8, -+ 0xfdf17746497f7052, -+ 0xfeb6ea8bedefa633, -+ 0xfe64a52ee96b8fc0, -+ 0x3dfdce7aa3c673b0, -+ 0x6bea10ca65c084e, -+ 0x486e494fcff30a62, -+ 0x5a89dba3c3efccfa, -+ 0xf89629465a75e01c, -+ 0xf6bbb397f1135823, -+ 0x746aa07ded582e2c, -+ 0xa8c2a44eb4571cdc, -+ 0x92f34d62616ce413, -+ 0x77b020baf9c81d17, -+ 0xace1474dc1d122e, -+ 0xd819992132456ba, -+ 0x10e1fff697ed6c69, -+ 0xca8d3ffa1ef463c1, -+ 0xbd308ff8a6b17cb2, -+ 0xac7cb3f6d05ddbde, -+ 0x6bcdf07a423aa96b, -+ 0x86c16c98d2c953c6, -+ 0xe871c7bf077ba8b7, -+ 0x11471cd764ad4972, -+ 0xd598e40d3dd89bcf, -+ 0x4aff1d108d4ec2c3, -+ 0xcedf722a585139ba, -+ 0xc2974eb4ee658828, -+ 0x733d226229feea32, -+ 0x806357d5a3f525f, -+ 0xca07c2dcb0cf26f7, -+ 0xfc89b393dd02f0b5, -+ 0xbbac2078d443ace2, -+ 0xd54b944b84aa4c0d, -+ 0xa9e795e65d4df11, -+ 0x4d4617b5ff4a16d5, -+ 0x504bced1bf8e4e45, -+ 0xe45ec2862f71e1d6, -+ 0x5d767327bb4e5a4c, -+ 0x3a6a07f8d510f86f, -+ 0x890489f70a55368b, -+ 0x2b45ac74ccea842e, -+ 0x3b0b8bc90012929d, -+ 0x9ce6ebb40173744, -+ 0xcc420a6a101d0515, -+ 0x9fa946824a12232d, -+ 0x47939822dc96abf9, -+ 0x59787e2b93bc56f7, -+ 0x57eb4edb3c55b65a, -+ 0xede622920b6b23f1, -+ 0xe95fab368e45eced, -+ 0x11dbcb0218ebb414, -+ 0xd652bdc29f26a119, -+ 0x4be76d3346f0495f, -+ 0x6f70a4400c562ddb, -+ 0xcb4ccd500f6bb952, -+ 0x7e2000a41346a7a7, -+ 0x8ed400668c0c28c8, -+ 0x728900802f0f32fa, -+ 0x4f2b40a03ad2ffb9, -+ 0xe2f610c84987bfa8, -+ 0xdd9ca7d2df4d7c9, -+ 0x91503d1c79720dbb, -+ 0x75a44c6397ce912a, -+ 0xc986afbe3ee11aba, -+ 0xfbe85badce996168, -+ 0xfae27299423fb9c3, -+ 0xdccd879fc967d41a, -+ 0x5400e987bbc1c920, -+ 0x290123e9aab23b68, -+ 0xf9a0b6720aaf6521, -+ 0xf808e40e8d5b3e69, -+ 0xb60b1d1230b20e04, -+ 0xb1c6f22b5e6f48c2, -+ 0x1e38aeb6360b1af3, -+ 0x25c6da63c38de1b0, -+ 0x579c487e5a38ad0e, -+ 0x2d835a9df0c6d851, -+ 0xf8e431456cf88e65, -+ 0x1b8e9ecb641b58ff, -+ 0xe272467e3d222f3f, -+ 0x5b0ed81dcc6abb0f, -+ 0x98e947129fc2b4e9, -+ 0x3f2398d747b36224, -+ 0x8eec7f0d19a03aad, -+ 0x1953cf68300424ac, -+ 0x5fa8c3423c052dd7, -+ 0x3792f412cb06794d, -+ 0xe2bbd88bbee40bd0, -+ 0x5b6aceaeae9d0ec4, -+ 0xf245825a5a445275, -+ 0xeed6e2f0f0d56712, -+ 0x55464dd69685606b, -+ 0xaa97e14c3c26b886, -+ 0xd53dd99f4b3066a8, -+ 0xe546a8038efe4029, -+ 0xde98520472bdd033, -+ 0x963e66858f6d4440, -+ 0xdde7001379a44aa8, -+ 0x5560c018580d5d52, -+ 0xaab8f01e6e10b4a6, -+ 0xcab3961304ca70e8, -+ 0x3d607b97c5fd0d22, -+ 0x8cb89a7db77c506a, -+ 0x77f3608e92adb242, -+ 0x55f038b237591ed3, -+ 0x6b6c46dec52f6688, -+ 0x2323ac4b3b3da015, -+ 0xabec975e0a0d081a, -+ 0x96e7bd358c904a21, -+ 0x7e50d64177da2e54, -+ 0xdde50bd1d5d0b9e9, -+ 0x955e4ec64b44e864, -+ 0xbd5af13bef0b113e, -+ 0xecb1ad8aeacdd58e, -+ 0x67de18eda5814af2, -+ 0x80eacf948770ced7, -+ 0xa1258379a94d028d, -+ 0x96ee45813a04330, -+ 0x8bca9d6e188853fc, -+ 0x775ea264cf55347d, -+ 0x95364afe032a819d, -+ 0x3a83ddbd83f52204, -+ 0xc4926a9672793542, -+ 0x75b7053c0f178293, -+ 0x5324c68b12dd6338, -+ 0xd3f6fc16ebca5e03, -+ 0x88f4bb1ca6bcf584, -+ 0x2b31e9e3d06c32e5, -+ 0x3aff322e62439fcf, -+ 0x9befeb9fad487c2, -+ 0x4c2ebe687989a9b3, -+ 0xf9d37014bf60a10, -+ 0x538484c19ef38c94, -+ 0x2865a5f206b06fb9, -+ 0xf93f87b7442e45d3, -+ 0xf78f69a51539d748, -+ 0xb573440e5a884d1b, -+ 0x31680a88f8953030, -+ 0xfdc20d2b36ba7c3d, -+ 0x3d32907604691b4c, -+ 0xa63f9a49c2c1b10f, -+ 0xfcf80dc33721d53, -+ 0xd3c36113404ea4a8, -+ 0x645a1cac083126e9, -+ 0x3d70a3d70a3d70a3, -+ 0xcccccccccccccccc, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x0, -+ 0x4000000000000000, -+ 0x5000000000000000, -+ 0xa400000000000000, -+ 0x4d00000000000000, -+ 0xf020000000000000, -+ 0x6c28000000000000, -+ 0xc732000000000000, -+ 0x3c7f400000000000, -+ 0x4b9f100000000000, -+ 0x1e86d40000000000, -+ 0x1314448000000000, -+ 0x17d955a000000000, -+ 0x5dcfab0800000000, -+ 0x5aa1cae500000000, -+ 0xf14a3d9e40000000, -+ 0x6d9ccd05d0000000, -+ 0xe4820023a2000000, -+ 0xdda2802c8a800000, -+ 0xd50b2037ad200000, -+ 0x4526f422cc340000, -+ 0x9670b12b7f410000, -+ 0x3c0cdd765f114000, -+ 0xa5880a69fb6ac800, -+ 0x8eea0d047a457a00, -+ 0x72a4904598d6d880, -+ 0x47a6da2b7f864750, -+ 0x999090b65f67d924, -+ 0xfff4b4e3f741cf6d, -+ 0xbff8f10e7a8921a4, -+ 0xaff72d52192b6a0d, -+ 0x9bf4f8a69f764490, -+ 0x2f236d04753d5b4, -+ 0x1d762422c946590, -+ 0x424d3ad2b7b97ef5, -+ 0xd2e0898765a7deb2, -+ 0x63cc55f49f88eb2f, -+ 0x3cbf6b71c76b25fb, -+ 0x8bef464e3945ef7a, -+ 0x97758bf0e3cbb5ac, -+ 0x3d52eeed1cbea317, -+ 0x4ca7aaa863ee4bdd, -+ 0x8fe8caa93e74ef6a, -+ 0xb3e2fd538e122b44, -+ 0x60dbbca87196b616, -+ 0xbc8955e946fe31cd, -+ 0x6babab6398bdbe41, -+ 0xc696963c7eed2dd1, -+ 0xfc1e1de5cf543ca2, -+ 0x3b25a55f43294bcb, -+ 0x49ef0eb713f39ebe, -+ 0x6e3569326c784337, -+ 0x49c2c37f07965404, -+ 0xdc33745ec97be906, -+ 0x69a028bb3ded71a3, -+ 0xc40832ea0d68ce0c, -+ 0xf50a3fa490c30190, -+ 0x792667c6da79e0fa, -+ 0x577001b891185938, -+ 0xed4c0226b55e6f86, -+ 0x544f8158315b05b4, -+ 0x696361ae3db1c721, -+ 0x3bc3a19cd1e38e9, -+ 0x4ab48a04065c723, -+ 0x62eb0d64283f9c76, -+ 0x3ba5d0bd324f8394, -+ 0xca8f44ec7ee36479, -+ 0x7e998b13cf4e1ecb, -+ 0x9e3fedd8c321a67e, -+ 0xc5cfe94ef3ea101e, -+ 0xbba1f1d158724a12, -+ 0x2a8a6e45ae8edc97, -+ 0xf52d09d71a3293bd, -+ 0x593c2626705f9c56, -+ 0x6f8b2fb00c77836c, -+ 0xb6dfb9c0f956447, -+ 0x4724bd4189bd5eac, -+ 0x58edec91ec2cb657, -+ 0x2f2967b66737e3ed, -+ 0xbd79e0d20082ee74, -+ 0xecd8590680a3aa11, -+ 0xe80e6f4820cc9495, -+ 0x3109058d147fdcdd, -+ 0xbd4b46f0599fd415, -+ 0x6c9e18ac7007c91a, -+ 0x3e2cf6bc604ddb0, -+ 0x84db8346b786151c, -+ 0xe612641865679a63, -+ 0x4fcb7e8f3f60c07e, -+ 0xe3be5e330f38f09d, -+ 0x5cadf5bfd3072cc5, -+ 0x73d9732fc7c8f7f6, -+ 0x2867e7fddcdd9afa, -+ 0xb281e1fd541501b8, -+ 0x1f225a7ca91a4226, -+ 0x3375788de9b06958, -+ 0x52d6b1641c83ae, -+ 0xc0678c5dbd23a49a, -+ 0xf840b7ba963646e0, -+ 0xb650e5a93bc3d898, -+ 0xa3e51f138ab4cebe, -+ 0xc66f336c36b10137, -+ 0xb80b0047445d4184, -+ 0xa60dc059157491e5, -+ 0x87c89837ad68db2f, -+ 0x29babe4598c311fb, -+ 0xf4296dd6fef3d67a, -+ 0x1899e4a65f58660c, -+ 0x5ec05dcff72e7f8f, -+ 0x76707543f4fa1f73, -+ 0x6a06494a791c53a8, -+ 0x487db9d17636892, -+ 0x45a9d2845d3c42b6, -+ 0xb8a2392ba45a9b2, -+ 0x8e6cac7768d7141e, -+ 0x3207d795430cd926, -+ 0x7f44e6bd49e807b8, -+ 0x5f16206c9c6209a6, -+ 0x36dba887c37a8c0f, -+ 0xc2494954da2c9789, -+ 0xf2db9baa10b7bd6c, -+ 0x6f92829494e5acc7, -+ 0xcb772339ba1f17f9, -+ 0xff2a760414536efb, -+ 0xfef5138519684aba, -+ 0x7eb258665fc25d69, -+ 0xef2f773ffbd97a61, -+ 0xaafb550ffacfd8fa, -+ 0x95ba2a53f983cf38, -+ 0xdd945a747bf26183, -+ 0x94f971119aeef9e4, -+ 0x7a37cd5601aab85d, -+ 0xac62e055c10ab33a, -+ 0x577b986b314d6009, -+ 0xed5a7e85fda0b80b, -+ 0x14588f13be847307, -+ 0x596eb2d8ae258fc8, -+ 0x6fca5f8ed9aef3bb, -+ 0x25de7bb9480d5854, -+ 0xaf561aa79a10ae6a, -+ 0x1b2ba1518094da04, -+ 0x90fb44d2f05d0842, -+ 0x353a1607ac744a53, -+ 0x42889b8997915ce8, -+ 0x69956135febada11, -+ 0x43fab9837e699095, -+ 0x94f967e45e03f4bb, -+ 0x1d1be0eebac278f5, -+ 0x6462d92a69731732, -+ 0x7d7b8f7503cfdcfe, -+ 0x5cda735244c3d43e, -+ 0x3a0888136afa64a7, -+ 0x88aaa1845b8fdd0, -+ 0x8aad549e57273d45, -+ 0x36ac54e2f678864b, -+ 0x84576a1bb416a7dd, -+ 0x656d44a2a11c51d5, -+ 0x9f644ae5a4b1b325, -+ 0x873d5d9f0dde1fee, -+ 0xa90cb506d155a7ea, -+ 0x9a7f12442d588f2, -+ 0xc11ed6d538aeb2f, -+ 0x8f1668c8a86da5fa, -+ 0xf96e017d694487bc, -+ 0x37c981dcc395a9ac, -+ 0x85bbe253f47b1417, -+ 0x93956d7478ccec8e, -+ 0x387ac8d1970027b2, -+ 0x6997b05fcc0319e, -+ 0x441fece3bdf81f03, -+ 0xd527e81cad7626c3, -+ 0x8a71e223d8d3b074, -+ 0xf6872d5667844e49, -+ 0xb428f8ac016561db, -+ 0xe13336d701beba52, -+ 0xecc0024661173473, -+ 0x27f002d7f95d0190, -+ 0x31ec038df7b441f4, -+ 0x7e67047175a15271, -+ 0xf0062c6e984d386, -+ 0x52c07b78a3e60868, -+ 0xa7709a56ccdf8a82, -+ 0x88a66076400bb691, -+ 0x6acff893d00ea435, -+ 0x583f6b8c4124d43, -+ 0xc3727a337a8b704a, -+ 0x744f18c0592e4c5c, -+ 0x1162def06f79df73, -+ 0x8addcb5645ac2ba8, -+ 0x6d953e2bd7173692, -+ 0xc8fa8db6ccdd0437, -+ 0x1d9c9892400a22a2, -+ 0x2503beb6d00cab4b, -+ 0x2e44ae64840fd61d, -+ 0x5ceaecfed289e5d2, -+ 0x7425a83e872c5f47, -+ 0xd12f124e28f77719, -+ 0x82bd6b70d99aaa6f, -+ 0x636cc64d1001550b, -+ 0x3c47f7e05401aa4e, -+ 0x65acfaec34810a71, -+ 0x7f1839a741a14d0d, -+ 0x1ede48111209a050, -+ 0x934aed0aab460432, -+ 0xf81da84d5617853f, -+ 0x36251260ab9d668e, -+ 0xc1d72b7c6b426019, -+ 0xb24cf65b8612f81f, -+ 0xdee033f26797b627, -+ 0x169840ef017da3b1, -+ 0x8e1f289560ee864e, -+ 0xf1a6f2bab92a27e2, -+ 0xae10af696774b1db, -+ 0xacca6da1e0a8ef29, -+ 0x17fd090a58d32af3, -+ 0xddfc4b4cef07f5b0, -+ 0x4abdaf101564f98e, -+ 0x9d6d1ad41abe37f1, -+ 0x84c86189216dc5ed, -+ 0x32fd3cf5b4e49bb4, -+ 0x3fbc8c33221dc2a1, -+ 0xfabaf3feaa5334a, -+ 0x29cb4d87f2a7400e, -+ 0x743e20e9ef511012, -+ 0x914da9246b255416, -+ 0x1ad089b6c2f7548e, -+ 0xa184ac2473b529b1, -+ 0xc9e5d72d90a2741e, -+ 0x7e2fa67c7a658892, -+ 0xddbb901b98feeab7, -+ 0x552a74227f3ea565, -+ 0xd53a88958f87275f, -+ 0x8a892abaf368f137, -+ 0x2d2b7569b0432d85, -+ 0x9c3b29620e29fc73, -+ 0x8349f3ba91b47b8f, -+ 0x241c70a936219a73, -+ 0xed238cd383aa0110, -+ 0xf4363804324a40aa, -+ 0xb143c6053edcd0d5, -+ 0xdd94b7868e94050a, -+ 0xca7cf2b4191c8326, -+ 0xfd1c2f611f63a3f0, -+ 0xbc633b39673c8cec, -+ 0xd5be0503e085d813, -+ 0x4b2d8644d8a74e18, -+ 0xddf8e7d60ed1219e, -+ 0xcabb90e5c942b503, -+ 0x3d6a751f3b936243, -+ 0xcc512670a783ad4, -+ 0x27fb2b80668b24c5, -+ 0xb1f9f660802dedf6, -+ 0x5e7873f8a0396973, -+ 0xdb0b487b6423e1e8, -+ 0x91ce1a9a3d2cda62, -+ 0x7641a140cc7810fb, -+ 0xa9e904c87fcb0a9d, -+ 0x546345fa9fbdcd44, -+ 0xa97c177947ad4095, -+ 0x49ed8eabcccc485d, -+ 0x5c68f256bfff5a74, -+ 0x73832eec6fff3111, -+ 0xc831fd53c5ff7eab, -+ 0xba3e7ca8b77f5e55, -+ 0x28ce1bd2e55f35eb, -+ 0x7980d163cf5b81b3, -+ 0xd7e105bcc332621f, -+ 0x8dd9472bf3fefaa7, -+ 0xb14f98f6f0feb951, -+ 0x6ed1bf9a569f33d3, -+ 0xa862f80ec4700c8, -+ 0xcd27bb612758c0fa, -+ 0x8038d51cb897789c, -+ 0xe0470a63e6bd56c3, -+ 0x1858ccfce06cac74, -+ 0xf37801e0c43ebc8, -+ 0xd30560258f54e6ba, -+ 0x47c6b82ef32a2069, -+ 0x4cdc331d57fa5441, -+ 0xe0133fe4adf8e952, -+ 0x58180fddd97723a6, -+ 0x570f09eaa7ea7648, -+]; -+ -+static POW10: [f64; 23] = [ -+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, -+ 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, - ]; - - macro_rules! deserialize_prim_number { -diff --git a/src/number.rs b/src/number.rs -index e56faee..5240b1f 100644 ---- a/src/number.rs -+++ b/src/number.rs -@@ -16,6 +16,7 @@ use serde::de::{IntoDeserializer, MapAccess}; - pub(crate) const TOKEN: &str = "$serde_json::private::Number"; - - /// Represents a JSON number, whether integer or floating point. -+#[repr(transparent)] - #[derive(Clone, Eq, PartialEq)] - pub struct Number { - n: N, -diff --git a/src/read.rs b/src/read.rs -index f8a8da8..64631ec 100644 ---- a/src/read.rs -+++ b/src/read.rs -@@ -55,6 +55,9 @@ pub trait Read<'de>: private::Sealed { - #[doc(hidden)] - fn byte_offset(&self) -> usize; - -+ #[doc(hidden)] -+ fn slice_looking_back(&self, start: usize) -> Option<&[u8]>; -+ - /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped - /// string until the next quotation mark using the given scratch space if - /// necessary. The scratch space is initially empty. -@@ -329,6 +332,10 @@ where - } - } - -+ fn slice_looking_back(&self, _start: usize) -> Option<&[u8]> { -+ unimplemented!() -+ } -+ - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.parse_str_bytes(scratch, true, as_str) - .map(Reference::Copied) -@@ -539,6 +546,14 @@ impl<'a> Read<'a> for SliceRead<'a> { - self.index - } - -+ fn slice_looking_back(&self, start: usize) -> Option<&[u8]> { -+ if self.byte_offset() > start { -+ Some(&self.slice[start..self.index]) -+ } else { -+ None -+ } -+ } -+ - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.parse_str_bytes(scratch, true, as_str) - } -@@ -671,6 +686,10 @@ impl<'a> Read<'a> for StrRead<'a> { - self.delegate.byte_offset() - } - -+ fn slice_looking_back(&self, start: usize) -> Option<&[u8]> { -+ self.delegate.slice_looking_back(start) -+ } -+ - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.delegate.parse_str_bytes(scratch, true, |_, bytes| { - // The input is assumed to be valid UTF-8 and the \u-escapes are -diff --git a/tests/test.rs b/tests/test.rs -index 38c9f54..a47093b 100644 ---- a/tests/test.rs -+++ b/tests/test.rs -@@ -899,6 +899,13 @@ fn test_parse_f64() { - 000000000000000000e-10", - 1e308, - ), -+ ("5e-324", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005), -+ ("31.245270191439438", 31.245270191439438), -+ ("-31.245270191439438", -31.245270191439438), -+ ("121.48791951161945", 121.48791951161945), -+ ("-121.48791951161945", -121.48791951161945), -+ ("100.78399658203125", 100.78399658203125), -+ ("-100.78399658203125", -100.78399658203125), - ]); - } - diff --git a/json/src/de.rs b/json/src/de.rs deleted file mode 100644 index 33675cde..00000000 --- a/json/src/de.rs +++ /dev/null @@ -1,3720 +0,0 @@ -//! Deserialize JSON data to a Rust data structure. - -use crate::error::{Error, ErrorCode, Result}; -use crate::lib::str::FromStr; -use crate::lib::*; -use crate::number::Number; -use crate::read::{self, Fused, Reference}; -use serde::de::{self, Expected, Unexpected}; -use serde::{forward_to_deserialize_any, serde_if_integer128}; - -#[cfg(feature = "arbitrary_precision")] -use crate::number::NumberDeserializer; - -pub use crate::read::{Read, SliceRead, StrRead}; - -#[cfg(feature = "std")] -pub use crate::read::IoRead; - -////////////////////////////////////////////////////////////////////////////// - -/// A structure that deserializes JSON into Rust values. -pub struct Deserializer { - read: R, - scratch: Vec, - remaining_depth: u8, - #[cfg(feature = "unbounded_depth")] - disable_recursion_limit: bool, -} - -impl<'de, R> Deserializer -where - R: read::Read<'de>, -{ - /// Create a JSON deserializer from one of the possible serde_json input - /// sources. - /// - /// Typically it is more convenient to use one of these methods instead: - /// - /// - Deserializer::from_str - /// - Deserializer::from_bytes - /// - Deserializer::from_reader - pub fn new(read: R) -> Self { - #[cfg(not(feature = "unbounded_depth"))] - { - Deserializer { - read: read, - scratch: Vec::new(), - remaining_depth: 128, - } - } - - #[cfg(feature = "unbounded_depth")] - { - Deserializer { - read: read, - scratch: Vec::new(), - remaining_depth: 128, - disable_recursion_limit: false, - } - } - } -} - -#[cfg(feature = "std")] -impl Deserializer> -where - R: crate::io::Read, -{ - /// Creates a JSON deserializer from an `io::Read`. - /// - /// Reader-based deserializers do not support deserializing borrowed types - /// like `&str`, since the `std::io::Read` trait has no non-copying methods - /// -- everything it does involves copying bytes out of the data source. - pub fn from_reader(reader: R) -> Self { - Deserializer::new(read::IoRead::new(reader)) - } -} - -impl<'a> Deserializer> { - /// Creates a JSON deserializer from a `&[u8]`. - pub fn from_slice(bytes: &'a [u8]) -> Self { - Deserializer::new(read::SliceRead::new(bytes)) - } -} - -impl<'a> Deserializer> { - /// Creates a JSON deserializer from a `&str`. - pub fn from_str(s: &'a str) -> Self { - Deserializer::new(read::StrRead::new(s)) - } -} - -macro_rules! overflow { - ($a:ident * 10 + $b:ident, $c:expr) => { - $a >= $c / 10 && ($a > $c / 10 || $b > $c % 10) - }; -} - -pub(crate) enum ParserNumber { - F64(f64), - U64(u64), - I64(i64), - #[cfg(feature = "arbitrary_precision")] - String(String), -} - -impl ParserNumber { - fn visit<'de, V>(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - match self { - ParserNumber::F64(x) => visitor.visit_f64(x), - ParserNumber::U64(x) => visitor.visit_u64(x), - ParserNumber::I64(x) => visitor.visit_i64(x), - #[cfg(feature = "arbitrary_precision")] - ParserNumber::String(x) => visitor.visit_map(NumberDeserializer { number: x.into() }), - } - } - - fn invalid_type(self, exp: &dyn Expected) -> Error { - match self { - ParserNumber::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp), - ParserNumber::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp), - ParserNumber::I64(x) => de::Error::invalid_type(Unexpected::Signed(x), exp), - #[cfg(feature = "arbitrary_precision")] - ParserNumber::String(_) => de::Error::invalid_type(Unexpected::Other("number"), exp), - } - } -} - -impl<'de, R: Read<'de>> Deserializer { - /// The `Deserializer::end` method should be called after a value has been fully deserialized. - /// This allows the `Deserializer` to validate that the input stream is at the end or that it - /// only has trailing whitespace. - pub fn end(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), - None => Ok(()), - } - } - - /// Turn a JSON deserializer into an iterator over values of type T. - pub fn into_iter(self) -> StreamDeserializer<'de, R, T> - where - T: de::Deserialize<'de>, - { - // This cannot be an implementation of std::iter::IntoIterator because - // we need the caller to choose what T is. - let offset = self.read.byte_offset(); - StreamDeserializer { - de: self, - offset: offset, - failed: false, - output: PhantomData, - lifetime: PhantomData, - } - } - - /// Parse arbitrarily deep JSON structures without any consideration for - /// overflowing the stack. - /// - /// You will want to provide some other way to protect against stack - /// overflows, such as by wrapping your Deserializer in the dynamically - /// growing stack adapter provided by the serde_stacker crate. Additionally - /// you will need to be careful around other recursive operations on the - /// parsed result which may overflow the stack after deserialization has - /// completed, including, but not limited to, Display and Debug and Drop - /// impls. - /// - /// *This method is only available if serde_json is built with the - /// `"unbounded_depth"` feature.* - /// - /// # Examples - /// - /// ``` - /// use serde::Deserialize; - /// use serde_json::Value; - /// - /// fn main() { - /// let mut json = String::new(); - /// for _ in 0..10000 { - /// json = format!("[{}]", json); - /// } - /// - /// let mut deserializer = serde_json::Deserializer::from_str(&json); - /// deserializer.disable_recursion_limit(); - /// let deserializer = serde_stacker::Deserializer::new(&mut deserializer); - /// let value = Value::deserialize(deserializer).unwrap(); - /// - /// carefully_drop_nested_arrays(value); - /// } - /// - /// fn carefully_drop_nested_arrays(value: Value) { - /// let mut stack = vec![value]; - /// while let Some(value) = stack.pop() { - /// if let Value::Array(array) = value { - /// stack.extend(array); - /// } - /// } - /// } - /// ``` - #[cfg(feature = "unbounded_depth")] - pub fn disable_recursion_limit(&mut self) { - self.disable_recursion_limit = true; - } - - fn peek(&mut self) -> Result> { - self.read.peek() - } - - fn peek_or_null(&mut self) -> Result { - Ok(tri!(self.peek()).unwrap_or(b'\x00')) - } - - fn eat_char(&mut self) { - self.read.discard(); - } - - fn next_char(&mut self) -> Result> { - self.read.next() - } - - fn next_char_or_null(&mut self) -> Result { - Ok(tri!(self.next_char()).unwrap_or(b'\x00')) - } - - /// Error caused by a byte from next_char(). - #[cold] - fn error(&self, reason: ErrorCode) -> Error { - let position = self.read.position(); - Error::syntax(reason, position.line, position.column) - } - - /// Error caused by a byte from peek(). - #[cold] - fn peek_error(&self, reason: ErrorCode) -> Error { - let position = self.read.peek_position(); - Error::syntax(reason, position.line, position.column) - } - - /// Returns the first non-whitespace byte without consuming it, or `None` if - /// EOF is encountered. - fn parse_whitespace(&mut self) -> Result> { - loop { - match tri!(self.peek()) { - Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => { - self.eat_char(); - } - other => { - return Ok(other); - } - } - } - } - - #[cold] - fn peek_invalid_type(&mut self, exp: &dyn Expected) -> Error { - let err = match self.peek_or_null().unwrap_or(b'\x00') { - b'n' => { - self.eat_char(); - if let Err(err) = self.parse_ident(b"ull") { - return err; - } - de::Error::invalid_type(Unexpected::Unit, exp) - } - b't' => { - self.eat_char(); - if let Err(err) = self.parse_ident(b"rue") { - return err; - } - de::Error::invalid_type(Unexpected::Bool(true), exp) - } - b'f' => { - self.eat_char(); - if let Err(err) = self.parse_ident(b"alse") { - return err; - } - de::Error::invalid_type(Unexpected::Bool(false), exp) - } - b'-' => { - self.eat_char(); - match self.parse_any_number(false) { - Ok(n) => n.invalid_type(exp), - Err(err) => return err, - } - } - b'0'..=b'9' => match self.parse_any_number(true) { - Ok(n) => n.invalid_type(exp), - Err(err) => return err, - }, - b'"' => { - self.eat_char(); - self.scratch.clear(); - match self.read.parse_str(&mut self.scratch) { - Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), - Err(err) => return err, - } - } - b'[' => de::Error::invalid_type(Unexpected::Seq, exp), - b'{' => de::Error::invalid_type(Unexpected::Map, exp), - _ => self.peek_error(ErrorCode::ExpectedSomeValue), - }; - - self.fix_position(err) - } - - fn deserialize_prim_number(&mut self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'-' => { - self.eat_char(); - tri!(self.parse_integer(false)).visit(visitor) - } - b'0'..=b'9' => tri!(self.parse_integer(true)).visit(visitor), - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - 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(()), - } - } - 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); - } - Ok(()) - } - _ => { - Err(self.error(ErrorCode::InvalidNumber)) - } - } - } - } - - #[cold] - fn fix_position(&self, err: Error) -> Error { - err.fix_position(move |code| self.error(code)) - } - - fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { - for expected in ident { - match tri!(self.next_char()) { - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - Some(next) => { - if next != *expected { - return Err(self.error(ErrorCode::ExpectedSomeIdent)); - } - } - } - } - - Ok(()) - } - - fn parse_integer(&mut self, positive: bool) -> Result { - let start = if positive { - self.read.byte_offset() - } else { - self.read.byte_offset() - 1 - }; - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - }; - - match next { - b'0' => { - // There can be only one leading '0'. - match tri!(self.peek_or_null()) { - b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), - _ => self.parse_number(positive, 0, start), - } - } - c @ b'1'..=b'9' => { - let mut res = (c - b'0') as u64; - - loop { - match tri!(self.peek_or_null()) { - c @ b'0'..=b'9' => { - self.eat_char(); - let digit = (c - b'0') as u64; - - // We need to be careful with overflow. If we can, try to keep the - // number as a `u64` until we grow too large. At that point, switch to - // parsing the value as a `f64`. - if overflow!(res * 10 + digit, u64::max_value()) { - return Ok(ParserNumber::F64(tri!(self.parse_long_integer( - positive, res, 1, // res * 10^1 - start, - )))); - } - - res = res * 10 + digit; - } - _ => { - return self.parse_number(positive, res, start); - } - } - } - } - _ => Err(self.error(ErrorCode::InvalidNumber)), - } - } - - fn parse_long_integer( - &mut self, - positive: bool, - significand: u64, - mut exponent: i32, - start: usize, - ) -> Result { - loop { - match tri!(self.peek_or_null()) { - b'0'..=b'9' => { - self.eat_char(); - // This could overflow... if your integer is gigabytes long. - // Ignore that possibility. - exponent += 1; - } - b'.' => { - return self.parse_decimal(positive, significand, exponent, start); - } - b'e' | b'E' => { - return self.parse_exponent(positive, significand, exponent, start); - } - _ => { - return self.f64_from_parts(positive, significand, exponent, start); - } - } - } - } - - fn parse_number( - &mut self, - positive: bool, - significand: u64, - start: usize, - ) -> Result { - Ok(match tri!(self.peek_or_null()) { - b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0, start))), - b'e' | b'E' => { - ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0, start))) - } - _ => { - if positive { - ParserNumber::U64(significand) - } else { - let neg = (significand as i64).wrapping_neg(); - - // Convert into a float if we underflow. - if neg > 0 { - ParserNumber::F64(-(significand as f64)) - } else { - ParserNumber::I64(neg) - } - } - } - }) - } - - fn parse_decimal( - &mut self, - positive: bool, - mut significand: u64, - mut exponent: i32, - start: usize, - ) -> Result { - self.eat_char(); - - let mut at_least_one_digit = false; - while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - let digit = (c - b'0') as u64; - at_least_one_digit = true; - - if overflow!(significand * 10 + digit, u64::max_value()) { - // The next multiply/add would overflow, so just ignore all - // further digits. - while let b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - } - break; - } - - significand = significand * 10 + digit; - exponent -= 1; - } - - if !at_least_one_digit { - match tri!(self.peek()) { - Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), - } - } - - match tri!(self.peek_or_null()) { - b'e' | b'E' => self.parse_exponent(positive, significand, exponent, start), - _ => self.f64_from_parts(positive, significand, exponent, start), - } - } - - fn parse_exponent( - &mut self, - positive: bool, - significand: u64, - starting_exp: i32, - start: usize, - ) -> Result { - self.eat_char(); - - let positive_exp = match tri!(self.peek_or_null()) { - b'+' => { - self.eat_char(); - true - } - b'-' => { - self.eat_char(); - false - } - _ => true, - }; - - let next = match tri!(self.next_char()) { - Some(b) => b, - None => { - return Err(self.error(ErrorCode::EofWhileParsingValue)); - } - }; - - // Make sure a digit follows the exponent place. - let mut exp = match next { - c @ b'0'..=b'9' => (c - b'0') as i32, - _ => { - return Err(self.error(ErrorCode::InvalidNumber)); - } - }; - - while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - let digit = (c - b'0') as i32; - - if overflow!(exp * 10 + digit, i32::max_value()) { - return self.parse_exponent_overflow(positive, significand, positive_exp); - } - - exp = exp * 10 + digit; - } - - let final_exp = if positive_exp { - starting_exp.saturating_add(exp) - } else { - starting_exp.saturating_sub(exp) - }; - - self.f64_from_parts(positive, significand, final_exp, start) - } - - // This cold code should not be inlined into the middle of the hot - // exponent-parsing loop above. - #[cold] - #[inline(never)] - fn parse_exponent_overflow( - &mut self, - positive: bool, - significand: u64, - positive_exp: bool, - ) -> Result { - // Error instead of +/- infinity. - if significand != 0 && positive_exp { - return Err(self.error(ErrorCode::NumberOutOfRange)); - } - - while let b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - } - Ok(if positive { 0.0 } else { -0.0 }) - } - - fn parse_any_signed_number(&mut self) -> Result { - let peek = match tri!(self.peek()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'-' => { - self.eat_char(); - self.parse_any_number(false) - } - b'0'..=b'9' => self.parse_any_number(true), - _ => Err(self.peek_error(ErrorCode::InvalidNumber)), - }; - - let value = match tri!(self.peek()) { - Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)), - None => value, - }; - - match value { - Ok(value) => Ok(value), - // The de::Error impl creates errors with unknown line and column. - // Fill in the position here by looking at the current index in the - // input. There is no way to tell whether this should call `error` - // or `peek_error` so pick the one that seems correct more often. - // Worst case, the position is off by one character. - Err(err) => Err(self.fix_position(err)), - } - } - - #[cfg(not(feature = "arbitrary_precision"))] - fn parse_any_number(&mut self, positive: bool) -> Result { - self.parse_integer(positive) - } - - #[cfg(feature = "arbitrary_precision")] - fn parse_any_number(&mut self, positive: bool) -> Result { - let mut buf = String::with_capacity(16); - if !positive { - buf.push('-'); - } - self.scan_integer(&mut buf)?; - Ok(ParserNumber::String(buf)) - } - - #[cfg(feature = "arbitrary_precision")] - fn scan_or_eof(&mut self, buf: &mut String) -> Result { - match tri!(self.next_char()) { - Some(b) => { - buf.push(b as char); - Ok(b) - } - None => Err(self.error(ErrorCode::EofWhileParsingValue)), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn scan_integer(&mut self, buf: &mut String) -> Result<()> { - match tri!(self.scan_or_eof(buf)) { - b'0' => { - // There can be only one leading '0'. - match tri!(self.peek_or_null()) { - b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), - _ => self.scan_number(buf), - } - } - b'1'..=b'9' => loop { - match tri!(self.peek_or_null()) { - c @ b'0'..=b'9' => { - self.eat_char(); - buf.push(c as char); - } - _ => { - return self.scan_number(buf); - } - } - }, - _ => Err(self.error(ErrorCode::InvalidNumber)), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn scan_number(&mut self, buf: &mut String) -> Result<()> { - match tri!(self.peek_or_null()) { - b'.' => self.scan_decimal(buf), - b'e' | b'E' => self.scan_exponent(buf), - _ => Ok(()), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn scan_decimal(&mut self, buf: &mut String) -> Result<()> { - self.eat_char(); - buf.push('.'); - - let mut at_least_one_digit = false; - while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - buf.push(c as char); - at_least_one_digit = true; - } - - if !at_least_one_digit { - match tri!(self.peek()) { - Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)), - } - } - - match tri!(self.peek_or_null()) { - b'e' | b'E' => self.scan_exponent(buf), - _ => Ok(()), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn scan_exponent(&mut self, buf: &mut String) -> Result<()> { - self.eat_char(); - buf.push('e'); - - match tri!(self.peek_or_null()) { - b'+' => { - self.eat_char(); - } - b'-' => { - self.eat_char(); - buf.push('-'); - } - _ => {} - } - - // Make sure a digit follows the exponent place. - match tri!(self.scan_or_eof(buf)) { - b'0'..=b'9' => {} - _ => { - return Err(self.error(ErrorCode::InvalidNumber)); - } - } - - while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - buf.push(c as char); - } - - Ok(()) - } - - fn f64_from_parts( - &mut self, - positive: bool, - significand: u64, - exponent: i32, - start: usize, - ) -> Result { - if -22 <= exponent && exponent <= 22 && significand <= 9007199254740991 { - let mut f = significand as f64; - if exponent < 0 { - f = f / POW10[-exponent as usize]; - } else { - f = f * POW10[exponent as usize]; - } - Ok(if positive { f } else { -f }) - } else if significand == 0 { - Ok(if positive { 0.0 } else { -0.0 }) - } else if exponent >= -325 && exponent <= 308 { - let (factor_mantissa, factor_exponent) = POW10_COMPONENTS[(exponent + 325) as usize]; - let mut leading_zeroes = significand.leading_zeros() as u64; - let f = significand << leading_zeroes; - let (mut lower, mut upper) = multiply_as_u128(f, factor_mantissa); - if upper & 0x1FF == 0x1FF && lower.wrapping_add(f) < lower { - let factor_mantissa_low = MANTISSA_128[(exponent + 325) as usize]; - let (product_low, product_middle2) = multiply_as_u128(f, factor_mantissa_low); - let product_middle1 = lower; - let mut product_high = upper; - let product_middle = product_middle1.wrapping_add(product_middle2); - if product_middle < product_middle1 { - product_high += 1; - } - if product_middle.wrapping_add(1) == 0 - && product_high & 0x1FF == 0x1FF - && product_low.wrapping_add(f) < product_low - { - return self.f64_from_parts_slow(start); - } - upper = product_high; - lower = product_middle; - } - let upperbit = upper.wrapping_shr(63); - let mut mantissa = upper.wrapping_shr((upperbit + 9) as u32); - leading_zeroes += 1 ^ upperbit; - - if lower == 0 && upper & 0x1FF == 0 && mantissa & 3 == 1 { - return self.f64_from_parts_slow(start); - } - mantissa += mantissa & 1; - mantissa >>= 1; - - if mantissa >= 1 << 53 { - mantissa = 1 << 52; - leading_zeroes -= 1; - } - mantissa &= !(1 << 52); - let real_exponent = (factor_exponent as u64).wrapping_sub(leading_zeroes); - // we have to check that real_exponent is in range, otherwise we bail out - if real_exponent < 1 || real_exponent > 2046 { - return self.f64_from_parts_slow(start); - } - mantissa |= real_exponent.wrapping_shl(52); - mantissa |= (!positive as u64) << 63; - Ok(f64::from_bits(mantissa)) - } else { - self.f64_from_parts_slow(start) - } - } - - #[cold] - fn f64_from_parts_slow(&mut self, start: usize) -> Result { - let buf = self.read.slice_looking_back(start).unwrap(); - match lexical_core::parse_format::(buf, lexical_core::NumberFormat::JSON) { - Ok(val) => { - if val.is_infinite() { - Err(self.error(ErrorCode::NumberOutOfRange)) - } else { - Ok(val) - } - } - Err(err) => match err.code { - lexical_core::ErrorCode::ExponentWithoutFraction - | lexical_core::ErrorCode::MissingExponentSign - | lexical_core::ErrorCode::EmptyFraction - | lexical_core::ErrorCode::EmptyMantissa - | lexical_core::ErrorCode::EmptyExponent - | lexical_core::ErrorCode::MissingMantissaSign => { - Err(self.error(ErrorCode::EofWhileParsingValue)) - } - _ => Err(self.error(ErrorCode::InvalidNumber)), - }, - } - } - - fn parse_object_colon(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(b':') => { - self.eat_char(); - Ok(()) - } - Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), - } - } - - fn end_seq(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(b']') => { - self.eat_char(); - Ok(()) - } - Some(b',') => { - self.eat_char(); - match self.parse_whitespace() { - Ok(Some(b']')) => Err(self.peek_error(ErrorCode::TrailingComma)), - _ => Err(self.peek_error(ErrorCode::TrailingCharacters)), - } - } - Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingList)), - } - } - - fn end_map(&mut self) -> Result<()> { - match tri!(self.parse_whitespace()) { - Some(b'}') => { - self.eat_char(); - Ok(()) - } - Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)), - Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), - } - } - - fn ignore_value(&mut self) -> Result<()> { - self.scratch.clear(); - let mut enclosing = None; - - loop { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let frame = match peek { - b'n' => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - None - } - b't' => { - self.eat_char(); - tri!(self.parse_ident(b"rue")); - None - } - b'f' => { - self.eat_char(); - tri!(self.parse_ident(b"alse")); - None - } - b'-' => { - self.eat_char(); - tri!(self.ignore_integer()); - None - } - b'0'..=b'9' => { - tri!(self.ignore_integer()); - None - } - b'"' => { - self.eat_char(); - tri!(self.read.ignore_str()); - None - } - frame @ b'[' | frame @ b'{' => { - self.scratch.extend(enclosing.take()); - self.eat_char(); - Some(frame) - } - _ => return Err(self.peek_error(ErrorCode::ExpectedSomeValue)), - }; - - let (mut accept_comma, mut frame) = match frame { - Some(frame) => (false, frame), - None => match enclosing.take() { - Some(frame) => (true, frame), - None => match self.scratch.pop() { - Some(frame) => (true, frame), - None => return Ok(()), - }, - }, - }; - - loop { - match tri!(self.parse_whitespace()) { - Some(b',') if accept_comma => { - self.eat_char(); - break; - } - Some(b']') if frame == b'[' => {} - Some(b'}') if frame == b'{' => {} - Some(_) => { - if accept_comma { - return Err(self.peek_error(match frame { - b'[' => ErrorCode::ExpectedListCommaOrEnd, - b'{' => ErrorCode::ExpectedObjectCommaOrEnd, - _ => unreachable!(), - })); - } else { - break; - } - } - None => { - return Err(self.peek_error(match frame { - b'[' => ErrorCode::EofWhileParsingList, - b'{' => ErrorCode::EofWhileParsingObject, - _ => unreachable!(), - })); - } - } - - self.eat_char(); - frame = match self.scratch.pop() { - Some(frame) => frame, - None => return Ok(()), - }; - accept_comma = true; - } - - if frame == b'{' { - match tri!(self.parse_whitespace()) { - Some(b'"') => self.eat_char(), - Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), - } - tri!(self.read.ignore_str()); - match tri!(self.parse_whitespace()) { - Some(b':') => self.eat_char(), - Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)), - None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)), - } - } - - enclosing = Some(frame); - } - } - - fn ignore_integer(&mut self) -> Result<()> { - match tri!(self.next_char_or_null()) { - b'0' => { - // There can be only one leading '0'. - if let b'0'..=b'9' = tri!(self.peek_or_null()) { - return Err(self.peek_error(ErrorCode::InvalidNumber)); - } - } - b'1'..=b'9' => { - while let b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - } - } - _ => { - return Err(self.error(ErrorCode::InvalidNumber)); - } - } - - match tri!(self.peek_or_null()) { - b'.' => self.ignore_decimal(), - b'e' | b'E' => self.ignore_exponent(), - _ => Ok(()), - } - } - - fn ignore_decimal(&mut self) -> Result<()> { - self.eat_char(); - - let mut at_least_one_digit = false; - while let b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - at_least_one_digit = true; - } - - if !at_least_one_digit { - return Err(self.peek_error(ErrorCode::InvalidNumber)); - } - - match tri!(self.peek_or_null()) { - b'e' | b'E' => self.ignore_exponent(), - _ => Ok(()), - } - } - - fn ignore_exponent(&mut self) -> Result<()> { - self.eat_char(); - - match tri!(self.peek_or_null()) { - b'+' | b'-' => self.eat_char(), - _ => {} - } - - // Make sure a digit follows the exponent place. - match tri!(self.next_char_or_null()) { - b'0'..=b'9' => {} - _ => { - return Err(self.error(ErrorCode::InvalidNumber)); - } - } - - while let b'0'..=b'9' = tri!(self.peek_or_null()) { - self.eat_char(); - } - - Ok(()) - } - - #[cfg(feature = "raw_value")] - fn deserialize_raw_value(&mut self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.parse_whitespace()?; - self.read.begin_raw_buffering(); - self.ignore_value()?; - self.read.end_raw_buffering(visitor) - } -} - -impl FromStr for Number { - type Err = Error; - - fn from_str(s: &str) -> result::Result { - Deserializer::from_str(s) - .parse_any_signed_number() - .map(Into::into) - } -} - -fn multiply_as_u128(a: u64, b: u64) -> (u64, u64) { - let res: u128 = a as u128 * b as u128; - (res as u64, (res >> 64) as u64) -} - -static POW10_COMPONENTS: [(u64, i32); 634] = [ - (0xa5ced43b7e3e9188, 7), - (0xcf42894a5dce35ea, 10), - (0x818995ce7aa0e1b2, 14), - (0xa1ebfb4219491a1f, 17), - (0xca66fa129f9b60a6, 20), - (0xfd00b897478238d0, 23), - (0x9e20735e8cb16382, 27), - (0xc5a890362fddbc62, 30), - (0xf712b443bbd52b7b, 33), - (0x9a6bb0aa55653b2d, 37), - (0xc1069cd4eabe89f8, 40), - (0xf148440a256e2c76, 43), - (0x96cd2a865764dbca, 47), - (0xbc807527ed3e12bc, 50), - (0xeba09271e88d976b, 53), - (0x93445b8731587ea3, 57), - (0xb8157268fdae9e4c, 60), - (0xe61acf033d1a45df, 63), - (0x8fd0c16206306bab, 67), - (0xb3c4f1ba87bc8696, 70), - (0xe0b62e2929aba83c, 73), - (0x8c71dcd9ba0b4925, 77), - (0xaf8e5410288e1b6f, 80), - (0xdb71e91432b1a24a, 83), - (0x892731ac9faf056e, 87), - (0xab70fe17c79ac6ca, 90), - (0xd64d3d9db981787d, 93), - (0x85f0468293f0eb4e, 97), - (0xa76c582338ed2621, 100), - (0xd1476e2c07286faa, 103), - (0x82cca4db847945ca, 107), - (0xa37fce126597973c, 110), - (0xcc5fc196fefd7d0c, 113), - (0xff77b1fcbebcdc4f, 116), - (0x9faacf3df73609b1, 120), - (0xc795830d75038c1d, 123), - (0xf97ae3d0d2446f25, 126), - (0x9becce62836ac577, 130), - (0xc2e801fb244576d5, 133), - (0xf3a20279ed56d48a, 136), - (0x9845418c345644d6, 140), - (0xbe5691ef416bd60c, 143), - (0xedec366b11c6cb8f, 146), - (0x94b3a202eb1c3f39, 150), - (0xb9e08a83a5e34f07, 153), - (0xe858ad248f5c22c9, 156), - (0x91376c36d99995be, 160), - (0xb58547448ffffb2d, 163), - (0xe2e69915b3fff9f9, 166), - (0x8dd01fad907ffc3b, 170), - (0xb1442798f49ffb4a, 173), - (0xdd95317f31c7fa1d, 176), - (0x8a7d3eef7f1cfc52, 180), - (0xad1c8eab5ee43b66, 183), - (0xd863b256369d4a40, 186), - (0x873e4f75e2224e68, 190), - (0xa90de3535aaae202, 193), - (0xd3515c2831559a83, 196), - (0x8412d9991ed58091, 200), - (0xa5178fff668ae0b6, 203), - (0xce5d73ff402d98e3, 206), - (0x80fa687f881c7f8e, 210), - (0xa139029f6a239f72, 213), - (0xc987434744ac874e, 216), - (0xfbe9141915d7a922, 219), - (0x9d71ac8fada6c9b5, 223), - (0xc4ce17b399107c22, 226), - (0xf6019da07f549b2b, 229), - (0x99c102844f94e0fb, 233), - (0xc0314325637a1939, 236), - (0xf03d93eebc589f88, 239), - (0x96267c7535b763b5, 243), - (0xbbb01b9283253ca2, 246), - (0xea9c227723ee8bcb, 249), - (0x92a1958a7675175f, 253), - (0xb749faed14125d36, 256), - (0xe51c79a85916f484, 259), - (0x8f31cc0937ae58d2, 263), - (0xb2fe3f0b8599ef07, 266), - (0xdfbdcece67006ac9, 269), - (0x8bd6a141006042bd, 273), - (0xaecc49914078536d, 276), - (0xda7f5bf590966848, 279), - (0x888f99797a5e012d, 283), - (0xaab37fd7d8f58178, 286), - (0xd5605fcdcf32e1d6, 289), - (0x855c3be0a17fcd26, 293), - (0xa6b34ad8c9dfc06f, 296), - (0xd0601d8efc57b08b, 299), - (0x823c12795db6ce57, 303), - (0xa2cb1717b52481ed, 306), - (0xcb7ddcdda26da268, 309), - (0xfe5d54150b090b02, 312), - (0x9efa548d26e5a6e1, 316), - (0xc6b8e9b0709f109a, 319), - (0xf867241c8cc6d4c0, 322), - (0x9b407691d7fc44f8, 326), - (0xc21094364dfb5636, 329), - (0xf294b943e17a2bc4, 332), - (0x979cf3ca6cec5b5a, 336), - (0xbd8430bd08277231, 339), - (0xece53cec4a314ebd, 342), - (0x940f4613ae5ed136, 346), - (0xb913179899f68584, 349), - (0xe757dd7ec07426e5, 352), - (0x9096ea6f3848984f, 356), - (0xb4bca50b065abe63, 359), - (0xe1ebce4dc7f16dfb, 362), - (0x8d3360f09cf6e4bd, 366), - (0xb080392cc4349dec, 369), - (0xdca04777f541c567, 372), - (0x89e42caaf9491b60, 376), - (0xac5d37d5b79b6239, 379), - (0xd77485cb25823ac7, 382), - (0x86a8d39ef77164bc, 386), - (0xa8530886b54dbdeb, 389), - (0xd267caa862a12d66, 392), - (0x8380dea93da4bc60, 396), - (0xa46116538d0deb78, 399), - (0xcd795be870516656, 402), - (0x806bd9714632dff6, 406), - (0xa086cfcd97bf97f3, 409), - (0xc8a883c0fdaf7df0, 412), - (0xfad2a4b13d1b5d6c, 415), - (0x9cc3a6eec6311a63, 419), - (0xc3f490aa77bd60fc, 422), - (0xf4f1b4d515acb93b, 425), - (0x991711052d8bf3c5, 429), - (0xbf5cd54678eef0b6, 432), - (0xef340a98172aace4, 435), - (0x9580869f0e7aac0e, 439), - (0xbae0a846d2195712, 442), - (0xe998d258869facd7, 445), - (0x91ff83775423cc06, 449), - (0xb67f6455292cbf08, 452), - (0xe41f3d6a7377eeca, 455), - (0x8e938662882af53e, 459), - (0xb23867fb2a35b28d, 462), - (0xdec681f9f4c31f31, 465), - (0x8b3c113c38f9f37e, 469), - (0xae0b158b4738705e, 472), - (0xd98ddaee19068c76, 475), - (0x87f8a8d4cfa417c9, 479), - (0xa9f6d30a038d1dbc, 482), - (0xd47487cc8470652b, 485), - (0x84c8d4dfd2c63f3b, 489), - (0xa5fb0a17c777cf09, 492), - (0xcf79cc9db955c2cc, 495), - (0x81ac1fe293d599bf, 499), - (0xa21727db38cb002f, 502), - (0xca9cf1d206fdc03b, 505), - (0xfd442e4688bd304a, 508), - (0x9e4a9cec15763e2e, 512), - (0xc5dd44271ad3cdba, 515), - (0xf7549530e188c128, 518), - (0x9a94dd3e8cf578b9, 522), - (0xc13a148e3032d6e7, 525), - (0xf18899b1bc3f8ca1, 528), - (0x96f5600f15a7b7e5, 532), - (0xbcb2b812db11a5de, 535), - (0xebdf661791d60f56, 538), - (0x936b9fcebb25c995, 542), - (0xb84687c269ef3bfb, 545), - (0xe65829b3046b0afa, 548), - (0x8ff71a0fe2c2e6dc, 552), - (0xb3f4e093db73a093, 555), - (0xe0f218b8d25088b8, 558), - (0x8c974f7383725573, 562), - (0xafbd2350644eeacf, 565), - (0xdbac6c247d62a583, 568), - (0x894bc396ce5da772, 572), - (0xab9eb47c81f5114f, 575), - (0xd686619ba27255a2, 578), - (0x8613fd0145877585, 582), - (0xa798fc4196e952e7, 585), - (0xd17f3b51fca3a7a0, 588), - (0x82ef85133de648c4, 592), - (0xa3ab66580d5fdaf5, 595), - (0xcc963fee10b7d1b3, 598), - (0xffbbcfe994e5c61f, 601), - (0x9fd561f1fd0f9bd3, 605), - (0xc7caba6e7c5382c8, 608), - (0xf9bd690a1b68637b, 611), - (0x9c1661a651213e2d, 615), - (0xc31bfa0fe5698db8, 618), - (0xf3e2f893dec3f126, 621), - (0x986ddb5c6b3a76b7, 625), - (0xbe89523386091465, 628), - (0xee2ba6c0678b597f, 631), - (0x94db483840b717ef, 635), - (0xba121a4650e4ddeb, 638), - (0xe896a0d7e51e1566, 641), - (0x915e2486ef32cd60, 645), - (0xb5b5ada8aaff80b8, 648), - (0xe3231912d5bf60e6, 651), - (0x8df5efabc5979c8f, 655), - (0xb1736b96b6fd83b3, 658), - (0xddd0467c64bce4a0, 661), - (0x8aa22c0dbef60ee4, 665), - (0xad4ab7112eb3929d, 668), - (0xd89d64d57a607744, 671), - (0x87625f056c7c4a8b, 675), - (0xa93af6c6c79b5d2d, 678), - (0xd389b47879823479, 681), - (0x843610cb4bf160cb, 685), - (0xa54394fe1eedb8fe, 688), - (0xce947a3da6a9273e, 691), - (0x811ccc668829b887, 695), - (0xa163ff802a3426a8, 698), - (0xc9bcff6034c13052, 701), - (0xfc2c3f3841f17c67, 704), - (0x9d9ba7832936edc0, 708), - (0xc5029163f384a931, 711), - (0xf64335bcf065d37d, 714), - (0x99ea0196163fa42e, 718), - (0xc06481fb9bcf8d39, 721), - (0xf07da27a82c37088, 724), - (0x964e858c91ba2655, 728), - (0xbbe226efb628afea, 731), - (0xeadab0aba3b2dbe5, 734), - (0x92c8ae6b464fc96f, 738), - (0xb77ada0617e3bbcb, 741), - (0xe55990879ddcaabd, 744), - (0x8f57fa54c2a9eab6, 748), - (0xb32df8e9f3546564, 751), - (0xdff9772470297ebd, 754), - (0x8bfbea76c619ef36, 758), - (0xaefae51477a06b03, 761), - (0xdab99e59958885c4, 764), - (0x88b402f7fd75539b, 768), - (0xaae103b5fcd2a881, 771), - (0xd59944a37c0752a2, 774), - (0x857fcae62d8493a5, 778), - (0xa6dfbd9fb8e5b88e, 781), - (0xd097ad07a71f26b2, 784), - (0x825ecc24c873782f, 788), - (0xa2f67f2dfa90563b, 791), - (0xcbb41ef979346bca, 794), - (0xfea126b7d78186bc, 797), - (0x9f24b832e6b0f436, 801), - (0xc6ede63fa05d3143, 804), - (0xf8a95fcf88747d94, 807), - (0x9b69dbe1b548ce7c, 811), - (0xc24452da229b021b, 814), - (0xf2d56790ab41c2a2, 817), - (0x97c560ba6b0919a5, 821), - (0xbdb6b8e905cb600f, 824), - (0xed246723473e3813, 827), - (0x9436c0760c86e30b, 831), - (0xb94470938fa89bce, 834), - (0xe7958cb87392c2c2, 837), - (0x90bd77f3483bb9b9, 841), - (0xb4ecd5f01a4aa828, 844), - (0xe2280b6c20dd5232, 847), - (0x8d590723948a535f, 851), - (0xb0af48ec79ace837, 854), - (0xdcdb1b2798182244, 857), - (0x8a08f0f8bf0f156b, 861), - (0xac8b2d36eed2dac5, 864), - (0xd7adf884aa879177, 867), - (0x86ccbb52ea94baea, 871), - (0xa87fea27a539e9a5, 874), - (0xd29fe4b18e88640e, 877), - (0x83a3eeeef9153e89, 881), - (0xa48ceaaab75a8e2b, 884), - (0xcdb02555653131b6, 887), - (0x808e17555f3ebf11, 891), - (0xa0b19d2ab70e6ed6, 894), - (0xc8de047564d20a8b, 897), - (0xfb158592be068d2e, 900), - (0x9ced737bb6c4183d, 904), - (0xc428d05aa4751e4c, 907), - (0xf53304714d9265df, 910), - (0x993fe2c6d07b7fab, 914), - (0xbf8fdb78849a5f96, 917), - (0xef73d256a5c0f77c, 920), - (0x95a8637627989aad, 924), - (0xbb127c53b17ec159, 927), - (0xe9d71b689dde71af, 930), - (0x9226712162ab070d, 934), - (0xb6b00d69bb55c8d1, 937), - (0xe45c10c42a2b3b05, 940), - (0x8eb98a7a9a5b04e3, 944), - (0xb267ed1940f1c61c, 947), - (0xdf01e85f912e37a3, 950), - (0x8b61313bbabce2c6, 954), - (0xae397d8aa96c1b77, 957), - (0xd9c7dced53c72255, 960), - (0x881cea14545c7575, 964), - (0xaa242499697392d2, 967), - (0xd4ad2dbfc3d07787, 970), - (0x84ec3c97da624ab4, 974), - (0xa6274bbdd0fadd61, 977), - (0xcfb11ead453994ba, 980), - (0x81ceb32c4b43fcf4, 984), - (0xa2425ff75e14fc31, 987), - (0xcad2f7f5359a3b3e, 990), - (0xfd87b5f28300ca0d, 993), - (0x9e74d1b791e07e48, 997), - (0xc612062576589dda, 1000), - (0xf79687aed3eec551, 1003), - (0x9abe14cd44753b52, 1007), - (0xc16d9a0095928a27, 1010), - (0xf1c90080baf72cb1, 1013), - (0x971da05074da7bee, 1017), - (0xbce5086492111aea, 1020), - (0xec1e4a7db69561a5, 1023), - (0x9392ee8e921d5d07, 1027), - (0xb877aa3236a4b449, 1030), - (0xe69594bec44de15b, 1033), - (0x901d7cf73ab0acd9, 1037), - (0xb424dc35095cd80f, 1040), - (0xe12e13424bb40e13, 1043), - (0x8cbccc096f5088cb, 1047), - (0xafebff0bcb24aafe, 1050), - (0xdbe6fecebdedd5be, 1053), - (0x89705f4136b4a597, 1057), - (0xabcc77118461cefc, 1060), - (0xd6bf94d5e57a42bc, 1063), - (0x8637bd05af6c69b5, 1067), - (0xa7c5ac471b478423, 1070), - (0xd1b71758e219652b, 1073), - (0x83126e978d4fdf3b, 1077), - (0xa3d70a3d70a3d70a, 1080), - (0xcccccccccccccccc, 1083), - (0x8000000000000000, 1087), - (0xa000000000000000, 1090), - (0xc800000000000000, 1093), - (0xfa00000000000000, 1096), - (0x9c40000000000000, 1100), - (0xc350000000000000, 1103), - (0xf424000000000000, 1106), - (0x9896800000000000, 1110), - (0xbebc200000000000, 1113), - (0xee6b280000000000, 1116), - (0x9502f90000000000, 1120), - (0xba43b74000000000, 1123), - (0xe8d4a51000000000, 1126), - (0x9184e72a00000000, 1130), - (0xb5e620f480000000, 1133), - (0xe35fa931a0000000, 1136), - (0x8e1bc9bf04000000, 1140), - (0xb1a2bc2ec5000000, 1143), - (0xde0b6b3a76400000, 1146), - (0x8ac7230489e80000, 1150), - (0xad78ebc5ac620000, 1153), - (0xd8d726b7177a8000, 1156), - (0x878678326eac9000, 1160), - (0xa968163f0a57b400, 1163), - (0xd3c21bcecceda100, 1166), - (0x84595161401484a0, 1170), - (0xa56fa5b99019a5c8, 1173), - (0xcecb8f27f4200f3a, 1176), - (0x813f3978f8940984, 1180), - (0xa18f07d736b90be5, 1183), - (0xc9f2c9cd04674ede, 1186), - (0xfc6f7c4045812296, 1189), - (0x9dc5ada82b70b59d, 1193), - (0xc5371912364ce305, 1196), - (0xf684df56c3e01bc6, 1199), - (0x9a130b963a6c115c, 1203), - (0xc097ce7bc90715b3, 1206), - (0xf0bdc21abb48db20, 1209), - (0x96769950b50d88f4, 1213), - (0xbc143fa4e250eb31, 1216), - (0xeb194f8e1ae525fd, 1219), - (0x92efd1b8d0cf37be, 1223), - (0xb7abc627050305ad, 1226), - (0xe596b7b0c643c719, 1229), - (0x8f7e32ce7bea5c6f, 1233), - (0xb35dbf821ae4f38b, 1236), - (0xe0352f62a19e306e, 1239), - (0x8c213d9da502de45, 1243), - (0xaf298d050e4395d6, 1246), - (0xdaf3f04651d47b4c, 1249), - (0x88d8762bf324cd0f, 1253), - (0xab0e93b6efee0053, 1256), - (0xd5d238a4abe98068, 1259), - (0x85a36366eb71f041, 1263), - (0xa70c3c40a64e6c51, 1266), - (0xd0cf4b50cfe20765, 1269), - (0x82818f1281ed449f, 1273), - (0xa321f2d7226895c7, 1276), - (0xcbea6f8ceb02bb39, 1279), - (0xfee50b7025c36a08, 1282), - (0x9f4f2726179a2245, 1286), - (0xc722f0ef9d80aad6, 1289), - (0xf8ebad2b84e0d58b, 1292), - (0x9b934c3b330c8577, 1296), - (0xc2781f49ffcfa6d5, 1299), - (0xf316271c7fc3908a, 1302), - (0x97edd871cfda3a56, 1306), - (0xbde94e8e43d0c8ec, 1309), - (0xed63a231d4c4fb27, 1312), - (0x945e455f24fb1cf8, 1316), - (0xb975d6b6ee39e436, 1319), - (0xe7d34c64a9c85d44, 1322), - (0x90e40fbeea1d3a4a, 1326), - (0xb51d13aea4a488dd, 1329), - (0xe264589a4dcdab14, 1332), - (0x8d7eb76070a08aec, 1336), - (0xb0de65388cc8ada8, 1339), - (0xdd15fe86affad912, 1342), - (0x8a2dbf142dfcc7ab, 1346), - (0xacb92ed9397bf996, 1349), - (0xd7e77a8f87daf7fb, 1352), - (0x86f0ac99b4e8dafd, 1356), - (0xa8acd7c0222311bc, 1359), - (0xd2d80db02aabd62b, 1362), - (0x83c7088e1aab65db, 1366), - (0xa4b8cab1a1563f52, 1369), - (0xcde6fd5e09abcf26, 1372), - (0x80b05e5ac60b6178, 1376), - (0xa0dc75f1778e39d6, 1379), - (0xc913936dd571c84c, 1382), - (0xfb5878494ace3a5f, 1385), - (0x9d174b2dcec0e47b, 1389), - (0xc45d1df942711d9a, 1392), - (0xf5746577930d6500, 1395), - (0x9968bf6abbe85f20, 1399), - (0xbfc2ef456ae276e8, 1402), - (0xefb3ab16c59b14a2, 1405), - (0x95d04aee3b80ece5, 1409), - (0xbb445da9ca61281f, 1412), - (0xea1575143cf97226, 1415), - (0x924d692ca61be758, 1419), - (0xb6e0c377cfa2e12e, 1422), - (0xe498f455c38b997a, 1425), - (0x8edf98b59a373fec, 1429), - (0xb2977ee300c50fe7, 1432), - (0xdf3d5e9bc0f653e1, 1435), - (0x8b865b215899f46c, 1439), - (0xae67f1e9aec07187, 1442), - (0xda01ee641a708de9, 1445), - (0x884134fe908658b2, 1449), - (0xaa51823e34a7eede, 1452), - (0xd4e5e2cdc1d1ea96, 1455), - (0x850fadc09923329e, 1459), - (0xa6539930bf6bff45, 1462), - (0xcfe87f7cef46ff16, 1465), - (0x81f14fae158c5f6e, 1469), - (0xa26da3999aef7749, 1472), - (0xcb090c8001ab551c, 1475), - (0xfdcb4fa002162a63, 1478), - (0x9e9f11c4014dda7e, 1482), - (0xc646d63501a1511d, 1485), - (0xf7d88bc24209a565, 1488), - (0x9ae757596946075f, 1492), - (0xc1a12d2fc3978937, 1495), - (0xf209787bb47d6b84, 1498), - (0x9745eb4d50ce6332, 1502), - (0xbd176620a501fbff, 1505), - (0xec5d3fa8ce427aff, 1508), - (0x93ba47c980e98cdf, 1512), - (0xb8a8d9bbe123f017, 1515), - (0xe6d3102ad96cec1d, 1518), - (0x9043ea1ac7e41392, 1522), - (0xb454e4a179dd1877, 1525), - (0xe16a1dc9d8545e94, 1528), - (0x8ce2529e2734bb1d, 1532), - (0xb01ae745b101e9e4, 1535), - (0xdc21a1171d42645d, 1538), - (0x899504ae72497eba, 1542), - (0xabfa45da0edbde69, 1545), - (0xd6f8d7509292d603, 1548), - (0x865b86925b9bc5c2, 1552), - (0xa7f26836f282b732, 1555), - (0xd1ef0244af2364ff, 1558), - (0x8335616aed761f1f, 1562), - (0xa402b9c5a8d3a6e7, 1565), - (0xcd036837130890a1, 1568), - (0x802221226be55a64, 1572), - (0xa02aa96b06deb0fd, 1575), - (0xc83553c5c8965d3d, 1578), - (0xfa42a8b73abbf48c, 1581), - (0x9c69a97284b578d7, 1585), - (0xc38413cf25e2d70d, 1588), - (0xf46518c2ef5b8cd1, 1591), - (0x98bf2f79d5993802, 1595), - (0xbeeefb584aff8603, 1598), - (0xeeaaba2e5dbf6784, 1601), - (0x952ab45cfa97a0b2, 1605), - (0xba756174393d88df, 1608), - (0xe912b9d1478ceb17, 1611), - (0x91abb422ccb812ee, 1615), - (0xb616a12b7fe617aa, 1618), - (0xe39c49765fdf9d94, 1621), - (0x8e41ade9fbebc27d, 1625), - (0xb1d219647ae6b31c, 1628), - (0xde469fbd99a05fe3, 1631), - (0x8aec23d680043bee, 1635), - (0xada72ccc20054ae9, 1638), - (0xd910f7ff28069da4, 1641), - (0x87aa9aff79042286, 1645), - (0xa99541bf57452b28, 1648), - (0xd3fa922f2d1675f2, 1651), - (0x847c9b5d7c2e09b7, 1655), - (0xa59bc234db398c25, 1658), - (0xcf02b2c21207ef2e, 1661), - (0x8161afb94b44f57d, 1665), - (0xa1ba1ba79e1632dc, 1668), - (0xca28a291859bbf93, 1671), - (0xfcb2cb35e702af78, 1674), - (0x9defbf01b061adab, 1678), - (0xc56baec21c7a1916, 1681), - (0xf6c69a72a3989f5b, 1684), - (0x9a3c2087a63f6399, 1688), - (0xc0cb28a98fcf3c7f, 1691), - (0xf0fdf2d3f3c30b9f, 1694), - (0x969eb7c47859e743, 1698), - (0xbc4665b596706114, 1701), - (0xeb57ff22fc0c7959, 1704), - (0x9316ff75dd87cbd8, 1708), - (0xb7dcbf5354e9bece, 1711), - (0xe5d3ef282a242e81, 1714), - (0x8fa475791a569d10, 1718), - (0xb38d92d760ec4455, 1721), - (0xe070f78d3927556a, 1724), - (0x8c469ab843b89562, 1728), - (0xaf58416654a6babb, 1731), - (0xdb2e51bfe9d0696a, 1734), - (0x88fcf317f22241e2, 1738), - (0xab3c2fddeeaad25a, 1741), - (0xd60b3bd56a5586f1, 1744), - (0x85c7056562757456, 1748), - (0xa738c6bebb12d16c, 1751), - (0xd106f86e69d785c7, 1754), - (0x82a45b450226b39c, 1758), - (0xa34d721642b06084, 1761), - (0xcc20ce9bd35c78a5, 1764), - (0xff290242c83396ce, 1767), - (0x9f79a169bd203e41, 1771), - (0xc75809c42c684dd1, 1774), - (0xf92e0c3537826145, 1777), - (0x9bbcc7a142b17ccb, 1781), - (0xc2abf989935ddbfe, 1784), - (0xf356f7ebf83552fe, 1787), - (0x98165af37b2153de, 1791), - (0xbe1bf1b059e9a8d6, 1794), - (0xeda2ee1c7064130c, 1797), - (0x9485d4d1c63e8be7, 1801), - (0xb9a74a0637ce2ee1, 1804), - (0xe8111c87c5c1ba99, 1807), - (0x910ab1d4db9914a0, 1811), - (0xb54d5e4a127f59c8, 1814), - (0xe2a0b5dc971f303a, 1817), - (0x8da471a9de737e24, 1821), - (0xb10d8e1456105dad, 1824), - (0xdd50f1996b947518, 1827), - (0x8a5296ffe33cc92f, 1831), - (0xace73cbfdc0bfb7b, 1834), - (0xd8210befd30efa5a, 1837), - (0x8714a775e3e95c78, 1841), - (0xa8d9d1535ce3b396, 1844), - (0xd31045a8341ca07c, 1847), - (0x83ea2b892091e44d, 1851), - (0xa4e4b66b68b65d60, 1854), - (0xce1de40642e3f4b9, 1857), - (0x80d2ae83e9ce78f3, 1861), - (0xa1075a24e4421730, 1864), - (0xc94930ae1d529cfc, 1867), - (0xfb9b7cd9a4a7443c, 1870), - (0x9d412e0806e88aa5, 1874), - (0xc491798a08a2ad4e, 1877), - (0xf5b5d7ec8acb58a2, 1880), - (0x9991a6f3d6bf1765, 1884), - (0xbff610b0cc6edd3f, 1887), - (0xeff394dcff8a948e, 1890), - (0x95f83d0a1fb69cd9, 1894), - (0xbb764c4ca7a4440f, 1897), - (0xea53df5fd18d5513, 1900), - (0x92746b9be2f8552c, 1904), - (0xb7118682dbb66a77, 1907), - (0xe4d5e82392a40515, 1910), - (0x8f05b1163ba6832d, 1914), - (0xb2c71d5bca9023f8, 1917), - (0xdf78e4b2bd342cf6, 1920), - (0x8bab8eefb6409c1a, 1924), - (0xae9672aba3d0c320, 1927), - (0xda3c0f568cc4f3e8, 1930), - (0x8865899617fb1871, 1934), - (0xaa7eebfb9df9de8d, 1937), - (0xd51ea6fa85785631, 1940), - (0x8533285c936b35de, 1944), - (0xa67ff273b8460356, 1947), - (0xd01fef10a657842c, 1950), - (0x8213f56a67f6b29b, 1954), - (0xa298f2c501f45f42, 1957), - (0xcb3f2f7642717713, 1960), - (0xfe0efb53d30dd4d7, 1963), - (0x9ec95d1463e8a506, 1967), - (0xc67bb4597ce2ce48, 1970), - (0xf81aa16fdc1b81da, 1973), - (0x9b10a4e5e9913128, 1977), - (0xc1d4ce1f63f57d72, 1980), - (0xf24a01a73cf2dccf, 1983), - (0x976e41088617ca01, 1987), - (0xbd49d14aa79dbc82, 1990), - (0xec9c459d51852ba2, 1993), - (0x93e1ab8252f33b45, 1997), - (0xb8da1662e7b00a17, 2000), - (0xe7109bfba19c0c9d, 2003), - (0x906a617d450187e2, 2007), - (0xb484f9dc9641e9da, 2010), - (0xe1a63853bbd26451, 2013), - (0x8d07e33455637eb2, 2017), - (0xb049dc016abc5e5f, 2020), - (0xdc5c5301c56b75f7, 2023), - (0x89b9b3e11b6329ba, 2027), - (0xac2820d9623bf429, 2030), - (0xd732290fbacaf133, 2033), - (0x867f59a9d4bed6c0, 2037), - (0xa81f301449ee8c70, 2040), - (0xd226fc195c6a2f8c, 2043), - (0x83585d8fd9c25db7, 2047), - (0xa42e74f3d032f525, 2050), - (0xcd3a1230c43fb26f, 2053), - (0x80444b5e7aa7cf85, 2057), - (0xa0555e361951c366, 2060), - (0xc86ab5c39fa63440, 2063), - (0xfa856334878fc150, 2066), - (0x9c935e00d4b9d8d2, 2070), - (0xc3b8358109e84f07, 2073), - (0xf4a642e14c6262c8, 2076), - (0x98e7e9cccfbd7dbd, 2080), - (0xbf21e44003acdd2c, 2083), - (0xeeea5d5004981478, 2086), - (0x95527a5202df0ccb, 2090), - (0xbaa718e68396cffd, 2093), - (0xe950df20247c83fd, 2096), - (0x91d28b7416cdd27e, 2100), - (0xb6472e511c81471d, 2103), - (0xe3d8f9e563a198e5, 2106), - (0x8e679c2f5e44ff8f, 2110), -]; - -const MANTISSA_128: [u64; 634] = [ - 0x419ea3bd35385e2d, - 0x52064cac828675b9, - 0x7343efebd1940993, - 0x1014ebe6c5f90bf8, - 0xd41a26e077774ef6, - 0x8920b098955522b4, - 0x55b46e5f5d5535b0, - 0xeb2189f734aa831d, - 0xa5e9ec7501d523e4, - 0x47b233c92125366e, - 0x999ec0bb696e840a, - 0xc00670ea43ca250d, - 0x380406926a5e5728, - 0xc605083704f5ecf2, - 0xf7864a44c633682e, - 0x7ab3ee6afbe0211d, - 0x5960ea05bad82964, - 0x6fb92487298e33bd, - 0xa5d3b6d479f8e056, - 0x8f48a4899877186c, - 0x331acdabfe94de87, - 0x9ff0c08b7f1d0b14, - 0x7ecf0ae5ee44dd9, - 0xc9e82cd9f69d6150, - 0xbe311c083a225cd2, - 0x6dbd630a48aaf406, - 0x92cbbccdad5b108, - 0x25bbf56008c58ea5, - 0xaf2af2b80af6f24e, - 0x1af5af660db4aee1, - 0x50d98d9fc890ed4d, - 0xe50ff107bab528a0, - 0x1e53ed49a96272c8, - 0x25e8e89c13bb0f7a, - 0x77b191618c54e9ac, - 0xd59df5b9ef6a2417, - 0x4b0573286b44ad1d, - 0x4ee367f9430aec32, - 0x229c41f793cda73f, - 0x6b43527578c1110f, - 0x830a13896b78aaa9, - 0x23cc986bc656d553, - 0x2cbfbe86b7ec8aa8, - 0x7bf7d71432f3d6a9, - 0xdaf5ccd93fb0cc53, - 0xd1b3400f8f9cff68, - 0x23100809b9c21fa1, - 0xabd40a0c2832a78a, - 0x16c90c8f323f516c, - 0xae3da7d97f6792e3, - 0x99cd11cfdf41779c, - 0x40405643d711d583, - 0x482835ea666b2572, - 0xda3243650005eecf, - 0x90bed43e40076a82, - 0x5a7744a6e804a291, - 0x711515d0a205cb36, - 0xd5a5b44ca873e03, - 0xe858790afe9486c2, - 0x626e974dbe39a872, - 0xfb0a3d212dc8128f, - 0x7ce66634bc9d0b99, - 0x1c1fffc1ebc44e80, - 0xa327ffb266b56220, - 0x4bf1ff9f0062baa8, - 0x6f773fc3603db4a9, - 0xcb550fb4384d21d3, - 0x7e2a53a146606a48, - 0x2eda7444cbfc426d, - 0xfa911155fefb5308, - 0x793555ab7eba27ca, - 0x4bc1558b2f3458de, - 0x9eb1aaedfb016f16, - 0x465e15a979c1cadc, - 0xbfacd89ec191ec9, - 0xcef980ec671f667b, - 0x82b7e12780e7401a, - 0xd1b2ecb8b0908810, - 0x861fa7e6dcb4aa15, - 0x67a791e093e1d49a, - 0xe0c8bb2c5c6d24e0, - 0x58fae9f773886e18, - 0xaf39a475506a899e, - 0x6d8406c952429603, - 0xc8e5087ba6d33b83, - 0xfb1e4a9a90880a64, - 0x5cf2eea09a55067f, - 0xf42faa48c0ea481e, - 0xf13b94daf124da26, - 0x76c53d08d6b70858, - 0x54768c4b0c64ca6e, - 0xa9942f5dcf7dfd09, - 0xd3f93b35435d7c4c, - 0xc47bc5014a1a6daf, - 0x359ab6419ca1091b, - 0xc30163d203c94b62, - 0x79e0de63425dcf1d, - 0x985915fc12f542e4, - 0x3e6f5b7b17b2939d, - 0xa705992ceecf9c42, - 0x50c6ff782a838353, - 0xa4f8bf5635246428, - 0x871b7795e136be99, - 0x28e2557b59846e3f, - 0x331aeada2fe589cf, - 0x3ff0d2c85def7621, - 0xfed077a756b53a9, - 0xd3e8495912c62894, - 0x64712dd7abbbd95c, - 0xbd8d794d96aacfb3, - 0xecf0d7a0fc5583a0, - 0xf41686c49db57244, - 0x311c2875c522ced5, - 0x7d633293366b828b, - 0xae5dff9c02033197, - 0xd9f57f830283fdfc, - 0xd072df63c324fd7b, - 0x4247cb9e59f71e6d, - 0x52d9be85f074e608, - 0x67902e276c921f8b, - 0xba1cd8a3db53b6, - 0x80e8a40eccd228a4, - 0x6122cd128006b2cd, - 0x796b805720085f81, - 0xcbe3303674053bb0, - 0xbedbfc4411068a9c, - 0xee92fb5515482d44, - 0x751bdd152d4d1c4a, - 0xd262d45a78a0635d, - 0x86fb897116c87c34, - 0xd45d35e6ae3d4da0, - 0x8974836059cca109, - 0x2bd1a438703fc94b, - 0x7b6306a34627ddcf, - 0x1a3bc84c17b1d542, - 0x20caba5f1d9e4a93, - 0x547eb47b7282ee9c, - 0xe99e619a4f23aa43, - 0x6405fa00e2ec94d4, - 0xde83bc408dd3dd04, - 0x9624ab50b148d445, - 0x3badd624dd9b0957, - 0xe54ca5d70a80e5d6, - 0x5e9fcf4ccd211f4c, - 0x7647c3200069671f, - 0x29ecd9f40041e073, - 0xf468107100525890, - 0x7182148d4066eeb4, - 0xc6f14cd848405530, - 0xb8ada00e5a506a7c, - 0xa6d90811f0e4851c, - 0x908f4a166d1da663, - 0x9a598e4e043287fe, - 0x40eff1e1853f29fd, - 0xd12bee59e68ef47c, - 0x82bb74f8301958ce, - 0xe36a52363c1faf01, - 0xdc44e6c3cb279ac1, - 0x29ab103a5ef8c0b9, - 0x7415d448f6b6f0e7, - 0x111b495b3464ad21, - 0xcab10dd900beec34, - 0x3d5d514f40eea742, - 0xcb4a5a3112a5112, - 0x47f0e785eaba72ab, - 0x59ed216765690f56, - 0x306869c13ec3532c, - 0x1e414218c73a13fb, - 0xe5d1929ef90898fa, - 0xdf45f746b74abf39, - 0x6b8bba8c328eb783, - 0x66ea92f3f326564, - 0xc80a537b0efefebd, - 0xbd06742ce95f5f36, - 0x2c48113823b73704, - 0xf75a15862ca504c5, - 0x9a984d73dbe722fb, - 0xc13e60d0d2e0ebba, - 0x318df905079926a8, - 0xfdf17746497f7052, - 0xfeb6ea8bedefa633, - 0xfe64a52ee96b8fc0, - 0x3dfdce7aa3c673b0, - 0x6bea10ca65c084e, - 0x486e494fcff30a62, - 0x5a89dba3c3efccfa, - 0xf89629465a75e01c, - 0xf6bbb397f1135823, - 0x746aa07ded582e2c, - 0xa8c2a44eb4571cdc, - 0x92f34d62616ce413, - 0x77b020baf9c81d17, - 0xace1474dc1d122e, - 0xd819992132456ba, - 0x10e1fff697ed6c69, - 0xca8d3ffa1ef463c1, - 0xbd308ff8a6b17cb2, - 0xac7cb3f6d05ddbde, - 0x6bcdf07a423aa96b, - 0x86c16c98d2c953c6, - 0xe871c7bf077ba8b7, - 0x11471cd764ad4972, - 0xd598e40d3dd89bcf, - 0x4aff1d108d4ec2c3, - 0xcedf722a585139ba, - 0xc2974eb4ee658828, - 0x733d226229feea32, - 0x806357d5a3f525f, - 0xca07c2dcb0cf26f7, - 0xfc89b393dd02f0b5, - 0xbbac2078d443ace2, - 0xd54b944b84aa4c0d, - 0xa9e795e65d4df11, - 0x4d4617b5ff4a16d5, - 0x504bced1bf8e4e45, - 0xe45ec2862f71e1d6, - 0x5d767327bb4e5a4c, - 0x3a6a07f8d510f86f, - 0x890489f70a55368b, - 0x2b45ac74ccea842e, - 0x3b0b8bc90012929d, - 0x9ce6ebb40173744, - 0xcc420a6a101d0515, - 0x9fa946824a12232d, - 0x47939822dc96abf9, - 0x59787e2b93bc56f7, - 0x57eb4edb3c55b65a, - 0xede622920b6b23f1, - 0xe95fab368e45eced, - 0x11dbcb0218ebb414, - 0xd652bdc29f26a119, - 0x4be76d3346f0495f, - 0x6f70a4400c562ddb, - 0xcb4ccd500f6bb952, - 0x7e2000a41346a7a7, - 0x8ed400668c0c28c8, - 0x728900802f0f32fa, - 0x4f2b40a03ad2ffb9, - 0xe2f610c84987bfa8, - 0xdd9ca7d2df4d7c9, - 0x91503d1c79720dbb, - 0x75a44c6397ce912a, - 0xc986afbe3ee11aba, - 0xfbe85badce996168, - 0xfae27299423fb9c3, - 0xdccd879fc967d41a, - 0x5400e987bbc1c920, - 0x290123e9aab23b68, - 0xf9a0b6720aaf6521, - 0xf808e40e8d5b3e69, - 0xb60b1d1230b20e04, - 0xb1c6f22b5e6f48c2, - 0x1e38aeb6360b1af3, - 0x25c6da63c38de1b0, - 0x579c487e5a38ad0e, - 0x2d835a9df0c6d851, - 0xf8e431456cf88e65, - 0x1b8e9ecb641b58ff, - 0xe272467e3d222f3f, - 0x5b0ed81dcc6abb0f, - 0x98e947129fc2b4e9, - 0x3f2398d747b36224, - 0x8eec7f0d19a03aad, - 0x1953cf68300424ac, - 0x5fa8c3423c052dd7, - 0x3792f412cb06794d, - 0xe2bbd88bbee40bd0, - 0x5b6aceaeae9d0ec4, - 0xf245825a5a445275, - 0xeed6e2f0f0d56712, - 0x55464dd69685606b, - 0xaa97e14c3c26b886, - 0xd53dd99f4b3066a8, - 0xe546a8038efe4029, - 0xde98520472bdd033, - 0x963e66858f6d4440, - 0xdde7001379a44aa8, - 0x5560c018580d5d52, - 0xaab8f01e6e10b4a6, - 0xcab3961304ca70e8, - 0x3d607b97c5fd0d22, - 0x8cb89a7db77c506a, - 0x77f3608e92adb242, - 0x55f038b237591ed3, - 0x6b6c46dec52f6688, - 0x2323ac4b3b3da015, - 0xabec975e0a0d081a, - 0x96e7bd358c904a21, - 0x7e50d64177da2e54, - 0xdde50bd1d5d0b9e9, - 0x955e4ec64b44e864, - 0xbd5af13bef0b113e, - 0xecb1ad8aeacdd58e, - 0x67de18eda5814af2, - 0x80eacf948770ced7, - 0xa1258379a94d028d, - 0x96ee45813a04330, - 0x8bca9d6e188853fc, - 0x775ea264cf55347d, - 0x95364afe032a819d, - 0x3a83ddbd83f52204, - 0xc4926a9672793542, - 0x75b7053c0f178293, - 0x5324c68b12dd6338, - 0xd3f6fc16ebca5e03, - 0x88f4bb1ca6bcf584, - 0x2b31e9e3d06c32e5, - 0x3aff322e62439fcf, - 0x9befeb9fad487c2, - 0x4c2ebe687989a9b3, - 0xf9d37014bf60a10, - 0x538484c19ef38c94, - 0x2865a5f206b06fb9, - 0xf93f87b7442e45d3, - 0xf78f69a51539d748, - 0xb573440e5a884d1b, - 0x31680a88f8953030, - 0xfdc20d2b36ba7c3d, - 0x3d32907604691b4c, - 0xa63f9a49c2c1b10f, - 0xfcf80dc33721d53, - 0xd3c36113404ea4a8, - 0x645a1cac083126e9, - 0x3d70a3d70a3d70a3, - 0xcccccccccccccccc, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x4000000000000000, - 0x5000000000000000, - 0xa400000000000000, - 0x4d00000000000000, - 0xf020000000000000, - 0x6c28000000000000, - 0xc732000000000000, - 0x3c7f400000000000, - 0x4b9f100000000000, - 0x1e86d40000000000, - 0x1314448000000000, - 0x17d955a000000000, - 0x5dcfab0800000000, - 0x5aa1cae500000000, - 0xf14a3d9e40000000, - 0x6d9ccd05d0000000, - 0xe4820023a2000000, - 0xdda2802c8a800000, - 0xd50b2037ad200000, - 0x4526f422cc340000, - 0x9670b12b7f410000, - 0x3c0cdd765f114000, - 0xa5880a69fb6ac800, - 0x8eea0d047a457a00, - 0x72a4904598d6d880, - 0x47a6da2b7f864750, - 0x999090b65f67d924, - 0xfff4b4e3f741cf6d, - 0xbff8f10e7a8921a4, - 0xaff72d52192b6a0d, - 0x9bf4f8a69f764490, - 0x2f236d04753d5b4, - 0x1d762422c946590, - 0x424d3ad2b7b97ef5, - 0xd2e0898765a7deb2, - 0x63cc55f49f88eb2f, - 0x3cbf6b71c76b25fb, - 0x8bef464e3945ef7a, - 0x97758bf0e3cbb5ac, - 0x3d52eeed1cbea317, - 0x4ca7aaa863ee4bdd, - 0x8fe8caa93e74ef6a, - 0xb3e2fd538e122b44, - 0x60dbbca87196b616, - 0xbc8955e946fe31cd, - 0x6babab6398bdbe41, - 0xc696963c7eed2dd1, - 0xfc1e1de5cf543ca2, - 0x3b25a55f43294bcb, - 0x49ef0eb713f39ebe, - 0x6e3569326c784337, - 0x49c2c37f07965404, - 0xdc33745ec97be906, - 0x69a028bb3ded71a3, - 0xc40832ea0d68ce0c, - 0xf50a3fa490c30190, - 0x792667c6da79e0fa, - 0x577001b891185938, - 0xed4c0226b55e6f86, - 0x544f8158315b05b4, - 0x696361ae3db1c721, - 0x3bc3a19cd1e38e9, - 0x4ab48a04065c723, - 0x62eb0d64283f9c76, - 0x3ba5d0bd324f8394, - 0xca8f44ec7ee36479, - 0x7e998b13cf4e1ecb, - 0x9e3fedd8c321a67e, - 0xc5cfe94ef3ea101e, - 0xbba1f1d158724a12, - 0x2a8a6e45ae8edc97, - 0xf52d09d71a3293bd, - 0x593c2626705f9c56, - 0x6f8b2fb00c77836c, - 0xb6dfb9c0f956447, - 0x4724bd4189bd5eac, - 0x58edec91ec2cb657, - 0x2f2967b66737e3ed, - 0xbd79e0d20082ee74, - 0xecd8590680a3aa11, - 0xe80e6f4820cc9495, - 0x3109058d147fdcdd, - 0xbd4b46f0599fd415, - 0x6c9e18ac7007c91a, - 0x3e2cf6bc604ddb0, - 0x84db8346b786151c, - 0xe612641865679a63, - 0x4fcb7e8f3f60c07e, - 0xe3be5e330f38f09d, - 0x5cadf5bfd3072cc5, - 0x73d9732fc7c8f7f6, - 0x2867e7fddcdd9afa, - 0xb281e1fd541501b8, - 0x1f225a7ca91a4226, - 0x3375788de9b06958, - 0x52d6b1641c83ae, - 0xc0678c5dbd23a49a, - 0xf840b7ba963646e0, - 0xb650e5a93bc3d898, - 0xa3e51f138ab4cebe, - 0xc66f336c36b10137, - 0xb80b0047445d4184, - 0xa60dc059157491e5, - 0x87c89837ad68db2f, - 0x29babe4598c311fb, - 0xf4296dd6fef3d67a, - 0x1899e4a65f58660c, - 0x5ec05dcff72e7f8f, - 0x76707543f4fa1f73, - 0x6a06494a791c53a8, - 0x487db9d17636892, - 0x45a9d2845d3c42b6, - 0xb8a2392ba45a9b2, - 0x8e6cac7768d7141e, - 0x3207d795430cd926, - 0x7f44e6bd49e807b8, - 0x5f16206c9c6209a6, - 0x36dba887c37a8c0f, - 0xc2494954da2c9789, - 0xf2db9baa10b7bd6c, - 0x6f92829494e5acc7, - 0xcb772339ba1f17f9, - 0xff2a760414536efb, - 0xfef5138519684aba, - 0x7eb258665fc25d69, - 0xef2f773ffbd97a61, - 0xaafb550ffacfd8fa, - 0x95ba2a53f983cf38, - 0xdd945a747bf26183, - 0x94f971119aeef9e4, - 0x7a37cd5601aab85d, - 0xac62e055c10ab33a, - 0x577b986b314d6009, - 0xed5a7e85fda0b80b, - 0x14588f13be847307, - 0x596eb2d8ae258fc8, - 0x6fca5f8ed9aef3bb, - 0x25de7bb9480d5854, - 0xaf561aa79a10ae6a, - 0x1b2ba1518094da04, - 0x90fb44d2f05d0842, - 0x353a1607ac744a53, - 0x42889b8997915ce8, - 0x69956135febada11, - 0x43fab9837e699095, - 0x94f967e45e03f4bb, - 0x1d1be0eebac278f5, - 0x6462d92a69731732, - 0x7d7b8f7503cfdcfe, - 0x5cda735244c3d43e, - 0x3a0888136afa64a7, - 0x88aaa1845b8fdd0, - 0x8aad549e57273d45, - 0x36ac54e2f678864b, - 0x84576a1bb416a7dd, - 0x656d44a2a11c51d5, - 0x9f644ae5a4b1b325, - 0x873d5d9f0dde1fee, - 0xa90cb506d155a7ea, - 0x9a7f12442d588f2, - 0xc11ed6d538aeb2f, - 0x8f1668c8a86da5fa, - 0xf96e017d694487bc, - 0x37c981dcc395a9ac, - 0x85bbe253f47b1417, - 0x93956d7478ccec8e, - 0x387ac8d1970027b2, - 0x6997b05fcc0319e, - 0x441fece3bdf81f03, - 0xd527e81cad7626c3, - 0x8a71e223d8d3b074, - 0xf6872d5667844e49, - 0xb428f8ac016561db, - 0xe13336d701beba52, - 0xecc0024661173473, - 0x27f002d7f95d0190, - 0x31ec038df7b441f4, - 0x7e67047175a15271, - 0xf0062c6e984d386, - 0x52c07b78a3e60868, - 0xa7709a56ccdf8a82, - 0x88a66076400bb691, - 0x6acff893d00ea435, - 0x583f6b8c4124d43, - 0xc3727a337a8b704a, - 0x744f18c0592e4c5c, - 0x1162def06f79df73, - 0x8addcb5645ac2ba8, - 0x6d953e2bd7173692, - 0xc8fa8db6ccdd0437, - 0x1d9c9892400a22a2, - 0x2503beb6d00cab4b, - 0x2e44ae64840fd61d, - 0x5ceaecfed289e5d2, - 0x7425a83e872c5f47, - 0xd12f124e28f77719, - 0x82bd6b70d99aaa6f, - 0x636cc64d1001550b, - 0x3c47f7e05401aa4e, - 0x65acfaec34810a71, - 0x7f1839a741a14d0d, - 0x1ede48111209a050, - 0x934aed0aab460432, - 0xf81da84d5617853f, - 0x36251260ab9d668e, - 0xc1d72b7c6b426019, - 0xb24cf65b8612f81f, - 0xdee033f26797b627, - 0x169840ef017da3b1, - 0x8e1f289560ee864e, - 0xf1a6f2bab92a27e2, - 0xae10af696774b1db, - 0xacca6da1e0a8ef29, - 0x17fd090a58d32af3, - 0xddfc4b4cef07f5b0, - 0x4abdaf101564f98e, - 0x9d6d1ad41abe37f1, - 0x84c86189216dc5ed, - 0x32fd3cf5b4e49bb4, - 0x3fbc8c33221dc2a1, - 0xfabaf3feaa5334a, - 0x29cb4d87f2a7400e, - 0x743e20e9ef511012, - 0x914da9246b255416, - 0x1ad089b6c2f7548e, - 0xa184ac2473b529b1, - 0xc9e5d72d90a2741e, - 0x7e2fa67c7a658892, - 0xddbb901b98feeab7, - 0x552a74227f3ea565, - 0xd53a88958f87275f, - 0x8a892abaf368f137, - 0x2d2b7569b0432d85, - 0x9c3b29620e29fc73, - 0x8349f3ba91b47b8f, - 0x241c70a936219a73, - 0xed238cd383aa0110, - 0xf4363804324a40aa, - 0xb143c6053edcd0d5, - 0xdd94b7868e94050a, - 0xca7cf2b4191c8326, - 0xfd1c2f611f63a3f0, - 0xbc633b39673c8cec, - 0xd5be0503e085d813, - 0x4b2d8644d8a74e18, - 0xddf8e7d60ed1219e, - 0xcabb90e5c942b503, - 0x3d6a751f3b936243, - 0xcc512670a783ad4, - 0x27fb2b80668b24c5, - 0xb1f9f660802dedf6, - 0x5e7873f8a0396973, - 0xdb0b487b6423e1e8, - 0x91ce1a9a3d2cda62, - 0x7641a140cc7810fb, - 0xa9e904c87fcb0a9d, - 0x546345fa9fbdcd44, - 0xa97c177947ad4095, - 0x49ed8eabcccc485d, - 0x5c68f256bfff5a74, - 0x73832eec6fff3111, - 0xc831fd53c5ff7eab, - 0xba3e7ca8b77f5e55, - 0x28ce1bd2e55f35eb, - 0x7980d163cf5b81b3, - 0xd7e105bcc332621f, - 0x8dd9472bf3fefaa7, - 0xb14f98f6f0feb951, - 0x6ed1bf9a569f33d3, - 0xa862f80ec4700c8, - 0xcd27bb612758c0fa, - 0x8038d51cb897789c, - 0xe0470a63e6bd56c3, - 0x1858ccfce06cac74, - 0xf37801e0c43ebc8, - 0xd30560258f54e6ba, - 0x47c6b82ef32a2069, - 0x4cdc331d57fa5441, - 0xe0133fe4adf8e952, - 0x58180fddd97723a6, - 0x570f09eaa7ea7648, -]; - -static POW10: [f64; 23] = [ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, - 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, -]; - -macro_rules! deserialize_prim_number { - ($method:ident) => { - fn $method(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_prim_number(visitor) - } - }; -} - -#[cfg(not(feature = "unbounded_depth"))] -macro_rules! if_checking_recursion_limit { - ($($body:tt)*) => { - $($body)* - }; -} - -#[cfg(feature = "unbounded_depth")] -macro_rules! if_checking_recursion_limit { - ($this:ident $($body:tt)*) => { - if !$this.disable_recursion_limit { - $this $($body)* - } - }; -} - -macro_rules! check_recursion { - ($this:ident $($body:tt)*) => { - if_checking_recursion_limit! { - $this.remaining_depth -= 1; - if $this.remaining_depth == 0 { - return Err($this.peek_error(ErrorCode::RecursionLimitExceeded)); - } - } - - $this $($body)* - - if_checking_recursion_limit! { - $this.remaining_depth += 1; - } - }; -} - -impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'n' => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - b't' => { - self.eat_char(); - tri!(self.parse_ident(b"rue")); - visitor.visit_bool(true) - } - b'f' => { - self.eat_char(); - tri!(self.parse_ident(b"alse")); - visitor.visit_bool(false) - } - b'-' => { - self.eat_char(); - tri!(self.parse_any_number(false)).visit(visitor) - } - b'0'..=b'9' => tri!(self.parse_any_number(true)).visit(visitor), - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str(&mut self.scratch)) { - Reference::Borrowed(s) => visitor.visit_borrowed_str(s), - Reference::Copied(s) => visitor.visit_str(s), - } - } - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } - - match (ret, self.end_map()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), - }; - - match value { - Ok(value) => Ok(value), - // The de::Error impl creates errors with unknown line and column. - // Fill in the position here by looking at the current index in the - // input. There is no way to tell whether this should call `error` - // or `peek_error` so pick the one that seems correct more often. - // Worst case, the position is off by one character. - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_bool(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b't' => { - self.eat_char(); - tri!(self.parse_ident(b"rue")); - visitor.visit_bool(true) - } - b'f' => { - self.eat_char(); - tri!(self.parse_ident(b"alse")); - visitor.visit_bool(false) - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - deserialize_prim_number!(deserialize_i8); - deserialize_prim_number!(deserialize_i16); - deserialize_prim_number!(deserialize_i32); - deserialize_prim_number!(deserialize_i64); - deserialize_prim_number!(deserialize_u8); - deserialize_prim_number!(deserialize_u16); - deserialize_prim_number!(deserialize_u32); - deserialize_prim_number!(deserialize_u64); - deserialize_prim_number!(deserialize_f32); - deserialize_prim_number!(deserialize_f64); - - serde_if_integer128! { - fn deserialize_i128(self, visitor: V) -> Result - 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)); - } - }; - - tri!(self.scan_integer128(&mut buf)); - - 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(self, visitor: V) -> Result - 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)); - } - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - } - - fn deserialize_char(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_str(visitor) - } - - fn deserialize_str(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str(&mut self.scratch)) { - Reference::Borrowed(s) => visitor.visit_borrowed_str(s), - Reference::Copied(s) => visitor.visit_str(s), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_string(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_str(visitor) - } - - /// Parses a JSON string as bytes. Note that this function does not check - /// whether the bytes represent a valid UTF-8 string. - /// - /// The relevant part of the JSON specification is Section 8.2 of [RFC - /// 7159]: - /// - /// > When all the strings represented in a JSON text are composed entirely - /// > of Unicode characters (however escaped), then that JSON text is - /// > interoperable in the sense that all software implementations that - /// > parse it will agree on the contents of names and of string values in - /// > objects and arrays. - /// > - /// > However, the ABNF in this specification allows member names and string - /// > values to contain bit sequences that cannot encode Unicode characters; - /// > for example, "\uDEAD" (a single unpaired UTF-16 surrogate). Instances - /// > of this have been observed, for example, when a library truncates a - /// > UTF-16 string without checking whether the truncation split a - /// > surrogate pair. The behavior of software that receives JSON texts - /// > containing such values is unpredictable; for example, implementations - /// > might return different values for the length of a string value or even - /// > suffer fatal runtime exceptions. - /// - /// [RFC 7159]: https://tools.ietf.org/html/rfc7159 - /// - /// The behavior of serde_json is specified to fail on non-UTF-8 strings - /// when deserializing into Rust UTF-8 string types such as String, and - /// succeed with non-UTF-8 bytes when deserializing using this method. - /// - /// Escape sequences are processed as usual, and for `\uXXXX` escapes it is - /// still checked if the hex number represents a valid Unicode code point. - /// - /// # Examples - /// - /// You can use this to parse JSON strings containing invalid UTF-8 bytes. - /// - /// ``` - /// use serde_bytes::ByteBuf; - /// - /// fn look_at_bytes() -> Result<(), serde_json::Error> { - /// let json_data = b"\"some bytes: \xe5\x00\xe5\""; - /// let bytes: ByteBuf = serde_json::from_slice(json_data)?; - /// - /// assert_eq!(b'\xe5', bytes[12]); - /// assert_eq!(b'\0', bytes[13]); - /// assert_eq!(b'\xe5', bytes[14]); - /// - /// Ok(()) - /// } - /// # - /// # look_at_bytes().unwrap(); - /// ``` - /// - /// Backslash escape sequences like `\n` are still interpreted and required - /// to be valid, and `\u` escape sequences are required to represent valid - /// Unicode code points. - /// - /// ``` - /// use serde_bytes::ByteBuf; - /// - /// fn look_at_bytes() { - /// let json_data = b"\"invalid unicode surrogate: \\uD801\""; - /// let parsed: Result = serde_json::from_slice(json_data); - /// - /// assert!(parsed.is_err()); - /// - /// let expected_msg = "unexpected end of hex escape at line 1 column 35"; - /// assert_eq!(expected_msg, parsed.unwrap_err().to_string()); - /// } - /// # - /// # look_at_bytes(); - /// ``` - fn deserialize_bytes(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'"' => { - self.eat_char(); - self.scratch.clear(); - match tri!(self.read.parse_str_raw(&mut self.scratch)) { - Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), - Reference::Copied(b) => visitor.visit_bytes(b), - } - } - b'[' => self.deserialize_seq(visitor), - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - #[inline] - fn deserialize_byte_buf(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_bytes(visitor) - } - - /// Parses a `null` as a None, and any other values as a `Some(...)`. - #[inline] - fn deserialize_option(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - match tri!(self.parse_whitespace()) { - Some(b'n') => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_none() - } - _ => visitor.visit_some(self), - } - } - - fn deserialize_unit(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'n' => { - self.eat_char(); - tri!(self.parse_ident(b"ull")); - visitor.visit_unit() - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_unit(visitor) - } - - /// Parses a newtype struct as the underlying value. - #[inline] - fn deserialize_newtype_struct(self, name: &str, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - #[cfg(feature = "raw_value")] - { - if name == crate::raw::TOKEN { - return self.deserialize_raw_value(visitor); - } - } - - let _ = name; - visitor.visit_newtype_struct(self) - } - - fn deserialize_seq(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_tuple(self, _len: usize, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_map(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } - - match (ret, self.end_map()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - fn deserialize_struct( - self, - _name: &'static str, - _fields: &'static [&'static str], - visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - let peek = match tri!(self.parse_whitespace()) { - Some(b) => b, - None => { - return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); - } - }; - - let value = match peek { - b'[' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_seq(SeqAccess::new(self)); - } - - match (ret, self.end_seq()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - b'{' => { - check_recursion! { - self.eat_char(); - let ret = visitor.visit_map(MapAccess::new(self)); - } - - match (ret, self.end_map()) { - (Ok(ret), Ok(())) => Ok(ret), - (Err(err), _) | (_, Err(err)) => Err(err), - } - } - _ => Err(self.peek_invalid_type(&visitor)), - }; - - match value { - Ok(value) => Ok(value), - Err(err) => Err(self.fix_position(err)), - } - } - - /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight - /// value, a `[..]`, or a `{..}`. - #[inline] - fn deserialize_enum( - self, - _name: &str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - match tri!(self.parse_whitespace()) { - Some(b'{') => { - check_recursion! { - self.eat_char(); - let value = tri!(visitor.visit_enum(VariantAccess::new(self))); - } - - match tri!(self.parse_whitespace()) { - Some(b'}') => { - self.eat_char(); - Ok(value) - } - Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)), - None => Err(self.error(ErrorCode::EofWhileParsingObject)), - } - } - Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)), - Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), - None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), - } - } - - fn deserialize_identifier(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.deserialize_str(visitor) - } - - fn deserialize_ignored_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - tri!(self.ignore_value()); - visitor.visit_unit() - } -} - -struct SeqAccess<'a, R: 'a> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, R: 'a> SeqAccess<'a, R> { - fn new(de: &'a mut Deserializer) -> Self { - SeqAccess { - de: de, - first: true, - } - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { - type Error = Error; - - fn next_element_seed(&mut self, seed: T) -> Result> - where - T: de::DeserializeSeed<'de>, - { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b']') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - tri!(self.de.parse_whitespace()) - } - Some(b) => { - if self.first { - self.first = false; - Some(b) - } else { - return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); - } - } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); - } - }; - - match peek { - Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))), - None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), - } - } -} - -struct MapAccess<'a, R: 'a> { - de: &'a mut Deserializer, - first: bool, -} - -impl<'a, R: 'a> MapAccess<'a, R> { - fn new(de: &'a mut Deserializer) -> Self { - MapAccess { - de: de, - first: true, - } - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> { - type Error = Error; - - fn next_key_seed(&mut self, seed: K) -> Result> - where - K: de::DeserializeSeed<'de>, - { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b'}') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - tri!(self.de.parse_whitespace()) - } - Some(b) => { - if self.first { - self.first = false; - Some(b) - } else { - return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); - } - } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); - } - }; - - match peek { - Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), - Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), - None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), - } - } - - fn next_value_seed(&mut self, seed: V) -> Result - where - V: de::DeserializeSeed<'de>, - { - tri!(self.de.parse_object_colon()); - - seed.deserialize(&mut *self.de) - } -} - -struct VariantAccess<'a, R: 'a> { - de: &'a mut Deserializer, -} - -impl<'a, R: 'a> VariantAccess<'a, R> { - fn new(de: &'a mut Deserializer) -> Self { - VariantAccess { de: de } - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for VariantAccess<'a, R> { - type Error = Error; - type Variant = Self; - - fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> - where - V: de::DeserializeSeed<'de>, - { - let val = tri!(seed.deserialize(&mut *self.de)); - tri!(self.de.parse_object_colon()); - Ok((val, self)) - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for VariantAccess<'a, R> { - type Error = Error; - - fn unit_variant(self) -> Result<()> { - de::Deserialize::deserialize(self.de) - } - - fn newtype_variant_seed(self, seed: T) -> Result - where - T: de::DeserializeSeed<'de>, - { - seed.deserialize(self.de) - } - - fn tuple_variant(self, _len: usize, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - de::Deserializer::deserialize_seq(self.de, visitor) - } - - fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result - where - V: de::Visitor<'de>, - { - de::Deserializer::deserialize_struct(self.de, "", fields, visitor) - } -} - -struct UnitVariantAccess<'a, R: 'a> { - de: &'a mut Deserializer, -} - -impl<'a, R: 'a> UnitVariantAccess<'a, R> { - fn new(de: &'a mut Deserializer) -> Self { - UnitVariantAccess { de: de } - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, R> { - type Error = Error; - type Variant = Self; - - fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> - where - V: de::DeserializeSeed<'de>, - { - let variant = tri!(seed.deserialize(&mut *self.de)); - Ok((variant, self)) - } -} - -impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, R> { - type Error = Error; - - fn unit_variant(self) -> Result<()> { - Ok(()) - } - - fn newtype_variant_seed(self, _seed: T) -> Result - where - T: de::DeserializeSeed<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"newtype variant", - )) - } - - fn tuple_variant(self, _len: usize, _visitor: V) -> Result - where - V: de::Visitor<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"tuple variant", - )) - } - - fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result - where - V: de::Visitor<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"struct variant", - )) - } -} - -/// Only deserialize from this after peeking a '"' byte! Otherwise it may -/// deserialize invalid JSON successfully. -struct MapKey<'a, R: 'a> { - de: &'a mut Deserializer, -} - -macro_rules! deserialize_integer_key { - ($method:ident => $visit:ident) => { - fn $method(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.de.eat_char(); - self.de.scratch.clear(); - let string = tri!(self.de.read.parse_str(&mut self.de.scratch)); - match (string.parse(), string) { - (Ok(integer), _) => visitor.$visit(integer), - (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), - (Err(_), Reference::Copied(s)) => visitor.visit_str(s), - } - } - }; -} - -impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R> -where - R: Read<'de>, -{ - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.de.eat_char(); - self.de.scratch.clear(); - match tri!(self.de.read.parse_str(&mut self.de.scratch)) { - Reference::Borrowed(s) => visitor.visit_borrowed_str(s), - Reference::Copied(s) => visitor.visit_str(s), - } - } - - deserialize_integer_key!(deserialize_i8 => visit_i8); - 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_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); - } - - #[inline] - fn deserialize_option(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - // Map keys cannot be null. - visitor.visit_some(self) - } - - #[inline] - fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_newtype_struct(self) - } - - #[inline] - fn deserialize_enum( - self, - name: &'static str, - variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - self.de.deserialize_enum(name, variants, visitor) - } - - #[inline] - fn deserialize_bytes(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.de.deserialize_bytes(visitor) - } - - #[inline] - fn deserialize_byte_buf(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - self.de.deserialize_bytes(visitor) - } - - forward_to_deserialize_any! { - bool f32 f64 char str string unit unit_struct seq tuple tuple_struct map - struct identifier ignored_any - } -} - -////////////////////////////////////////////////////////////////////////////// - -/// Iterator that deserializes a stream into multiple JSON values. -/// -/// A stream deserializer can be created from any JSON deserializer using the -/// `Deserializer::into_iter` method. -/// -/// The data can consist of any JSON value. Values need to be a self-delineating value e.g. -/// arrays, objects, or strings, or be followed by whitespace or a self-delineating value. -/// -/// ``` -/// use serde_json::{Deserializer, Value}; -/// -/// fn main() { -/// let data = "{\"k\": 3}1\"cool\"\"stuff\" 3{} [0, 1, 2]"; -/// -/// let stream = Deserializer::from_str(data).into_iter::(); -/// -/// for value in stream { -/// println!("{}", value.unwrap()); -/// } -/// } -/// ``` -pub struct StreamDeserializer<'de, R, T> { - de: Deserializer, - offset: usize, - failed: bool, - output: PhantomData, - lifetime: PhantomData<&'de ()>, -} - -impl<'de, R, T> StreamDeserializer<'de, R, T> -where - R: read::Read<'de>, - T: de::Deserialize<'de>, -{ - /// Create a JSON stream deserializer from one of the possible serde_json - /// input sources. - /// - /// Typically it is more convenient to use one of these methods instead: - /// - /// - Deserializer::from_str(...).into_iter() - /// - Deserializer::from_bytes(...).into_iter() - /// - Deserializer::from_reader(...).into_iter() - pub fn new(read: R) -> Self { - let offset = read.byte_offset(); - StreamDeserializer { - de: Deserializer::new(read), - offset: offset, - failed: false, - output: PhantomData, - lifetime: PhantomData, - } - } - - /// Returns the number of bytes so far deserialized into a successful `T`. - /// - /// If a stream deserializer returns an EOF error, new data can be joined to - /// `old_data[stream.byte_offset()..]` to try again. - /// - /// ``` - /// let data = b"[0] [1] ["; - /// - /// let de = serde_json::Deserializer::from_slice(data); - /// let mut stream = de.into_iter::>(); - /// assert_eq!(0, stream.byte_offset()); - /// - /// println!("{:?}", stream.next()); // [0] - /// assert_eq!(3, stream.byte_offset()); - /// - /// println!("{:?}", stream.next()); // [1] - /// assert_eq!(7, stream.byte_offset()); - /// - /// println!("{:?}", stream.next()); // error - /// assert_eq!(8, stream.byte_offset()); - /// - /// // If err.is_eof(), can join the remaining data to new data and continue. - /// let remaining = &data[stream.byte_offset()..]; - /// ``` - /// - /// *Note:* In the future this method may be changed to return the number of - /// bytes so far deserialized into a successful T *or* syntactically valid - /// JSON skipped over due to a type error. See [serde-rs/json#70] for an - /// example illustrating this. - /// - /// [serde-rs/json#70]: https://github.com/serde-rs/json/issues/70 - pub fn byte_offset(&self) -> usize { - self.offset - } - - fn peek_end_of_value(&mut self) -> Result<()> { - match tri!(self.de.peek()) { - Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b'"') | Some(b'[') - | Some(b']') | Some(b'{') | Some(b'}') | Some(b',') | Some(b':') | None => Ok(()), - Some(_) => { - let position = self.de.read.peek_position(); - Err(Error::syntax( - ErrorCode::TrailingCharacters, - position.line, - position.column, - )) - } - } - } -} - -impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T> -where - R: Read<'de>, - T: de::Deserialize<'de>, -{ - type Item = Result; - - fn next(&mut self) -> Option> { - if R::should_early_return_if_failed && self.failed { - return None; - } - - // skip whitespaces, if any - // this helps with trailing whitespaces, since whitespaces between - // values are handled for us. - match self.de.parse_whitespace() { - Ok(None) => { - self.offset = self.de.read.byte_offset(); - None - } - Ok(Some(b)) => { - // If the value does not have a clear way to show the end of the value - // (like numbers, null, true etc.) we have to look for whitespace or - // the beginning of a self-delineated value. - let self_delineated_value = match b { - b'[' | b'"' | b'{' => true, - _ => false, - }; - self.offset = self.de.read.byte_offset(); - let result = de::Deserialize::deserialize(&mut self.de); - - Some(match result { - Ok(value) => { - self.offset = self.de.read.byte_offset(); - if self_delineated_value { - Ok(value) - } else { - self.peek_end_of_value().map(|_| value) - } - } - Err(e) => { - self.de.read.set_failed(&mut self.failed); - Err(e) - } - }) - } - Err(e) => { - self.de.read.set_failed(&mut self.failed); - Some(Err(e)) - } - } - } -} - -impl<'de, R, T> FusedIterator for StreamDeserializer<'de, R, T> -where - R: Read<'de> + Fused, - T: de::Deserialize<'de>, -{ -} - -////////////////////////////////////////////////////////////////////////////// - -fn from_trait<'de, R, T>(read: R) -> Result -where - R: Read<'de>, - T: de::Deserialize<'de>, -{ - let mut de = Deserializer::new(read); - let value = tri!(de::Deserialize::deserialize(&mut de)); - - // Make sure the whole stream has been consumed. - tri!(de.end()); - Ok(value) -} - -/// Deserialize an instance of type `T` from an IO stream of JSON. -/// -/// The content of the IO stream is deserialized directly from the stream -/// without being buffered in memory by serde_json. -/// -/// When reading from a source against which short reads are not efficient, such -/// as a [`File`], you will want to apply your own buffering because serde_json -/// will not buffer the input. See [`std::io::BufReader`]. -/// -/// It is expected that the input stream ends after the deserialized object. -/// If the stream does not end, such as in the case of a persistent socket connection, -/// this function will not return. It is possible instead to deserialize from a prefix of an input -/// stream without looking for EOF by managing your own [`Deserializer`]. -/// -/// Note that counter to intuition, this function is usually slower than -/// reading a file completely into memory and then applying [`from_str`] -/// or [`from_slice`] on it. See [issue #160]. -/// -/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html -/// [`std::io::BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html -/// [`from_str`]: ./fn.from_str.html -/// [`from_slice`]: ./fn.from_slice.html -/// [issue #160]: https://github.com/serde-rs/json/issues/160 -/// -/// # Example -/// -/// Reading the contents of a file. -/// -/// ``` -/// use serde::Deserialize; -/// -/// use std::error::Error; -/// use std::fs::File; -/// use std::io::BufReader; -/// use std::path::Path; -/// -/// #[derive(Deserialize, Debug)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn read_user_from_file>(path: P) -> Result> { -/// // Open the file in read-only mode with buffer. -/// let file = File::open(path)?; -/// let reader = BufReader::new(file); -/// -/// // Read the JSON contents of the file as an instance of `User`. -/// let u = serde_json::from_reader(reader)?; -/// -/// // Return the `User`. -/// Ok(u) -/// } -/// -/// fn main() { -/// # } -/// # fn fake_main() { -/// let u = read_user_from_file("test.json").unwrap(); -/// println!("{:#?}", u); -/// } -/// ``` -/// -/// Reading from a persistent socket connection. -/// -/// ``` -/// use serde::Deserialize; -/// -/// use std::error::Error; -/// use std::net::{TcpListener, TcpStream}; -/// -/// #[derive(Deserialize, Debug)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn read_user_from_stream(tcp_stream: TcpStream) -> Result> { -/// let mut de = serde_json::Deserializer::from_reader(tcp_stream); -/// let u = User::deserialize(&mut de)?; -/// -/// Ok(u) -/// } -/// -/// fn main() { -/// # } -/// # fn fake_main() { -/// let listener = TcpListener::bind("127.0.0.1:4000").unwrap(); -/// -/// for stream in listener.incoming() { -/// println!("{:#?}", read_user_from_stream(stream.unwrap())); -/// } -/// } -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if the structure of the input does not match the -/// structure expected by `T`, for example if `T` is a struct type but the input -/// contains something other than a JSON map. It can also fail if the structure -/// is correct but `T`'s implementation of `Deserialize` decides that something -/// is wrong with the data, for example required struct fields are missing from -/// the JSON map or some number is too big to fit in the expected primitive -/// type. -#[cfg(feature = "std")] -pub fn from_reader(rdr: R) -> Result -where - R: crate::io::Read, - T: de::DeserializeOwned, -{ - from_trait(read::IoRead::new(rdr)) -} - -/// Deserialize an instance of type `T` from bytes of JSON text. -/// -/// # Example -/// -/// ``` -/// use serde::Deserialize; -/// -/// #[derive(Deserialize, Debug)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn main() { -/// // The type of `j` is `&[u8]` -/// let j = b" -/// { -/// \"fingerprint\": \"0xF9BA143B95FF6D82\", -/// \"location\": \"Menlo Park, CA\" -/// }"; -/// -/// let u: User = serde_json::from_slice(j).unwrap(); -/// println!("{:#?}", u); -/// } -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if the structure of the input does not match the -/// structure expected by `T`, for example if `T` is a struct type but the input -/// contains something other than a JSON map. It can also fail if the structure -/// is correct but `T`'s implementation of `Deserialize` decides that something -/// is wrong with the data, for example required struct fields are missing from -/// the JSON map or some number is too big to fit in the expected primitive -/// type. -pub fn from_slice<'a, T>(v: &'a [u8]) -> Result -where - T: de::Deserialize<'a>, -{ - from_trait(read::SliceRead::new(v)) -} - -/// Deserialize an instance of type `T` from a string of JSON text. -/// -/// # Example -/// -/// ``` -/// use serde::Deserialize; -/// -/// #[derive(Deserialize, Debug)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn main() { -/// // The type of `j` is `&str` -/// let j = " -/// { -/// \"fingerprint\": \"0xF9BA143B95FF6D82\", -/// \"location\": \"Menlo Park, CA\" -/// }"; -/// -/// let u: User = serde_json::from_str(j).unwrap(); -/// println!("{:#?}", u); -/// } -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if the structure of the input does not match the -/// structure expected by `T`, for example if `T` is a struct type but the input -/// contains something other than a JSON map. It can also fail if the structure -/// is correct but `T`'s implementation of `Deserialize` decides that something -/// is wrong with the data, for example required struct fields are missing from -/// the JSON map or some number is too big to fit in the expected primitive -/// type. -pub fn from_str<'a, T>(s: &'a str) -> Result -where - T: de::Deserialize<'a>, -{ - from_trait(read::StrRead::new(s)) -} diff --git a/json/src/error.rs b/json/src/error.rs deleted file mode 100644 index b3b12a7a..00000000 --- a/json/src/error.rs +++ /dev/null @@ -1,444 +0,0 @@ -//! When serializing or deserializing JSON goes wrong. - -use crate::io; -use crate::lib::str::FromStr; -use crate::lib::*; -use serde::{de, ser}; - -/// This type represents all possible errors that can occur when serializing or -/// deserializing JSON data. -pub struct Error { - /// This `Box` allows us to keep the size of `Error` as small as possible. A - /// larger `Error` type was substantially slower due to all the functions - /// that pass around `Result`. - err: Box, -} - -/// Alias for a `Result` with the error type `serde_json::Error`. -pub type Result = result::Result; - -impl Error { - /// One-based line number at which the error was detected. - /// - /// Characters in the first line of the input (before the first newline - /// character) are in line 1. - pub fn line(&self) -> usize { - self.err.line - } - - /// One-based column number at which the error was detected. - /// - /// The first character in the input and any characters immediately - /// following a newline character are in column 1. - /// - /// Note that errors may occur in column 0, for example if a read from an IO - /// stream fails immediately following a previously read newline character. - pub fn column(&self) -> usize { - self.err.column - } - - /// Categorizes the cause of this error. - /// - /// - `Category::Io` - failure to read or write bytes on an IO stream - /// - `Category::Syntax` - input that is not syntactically valid JSON - /// - `Category::Data` - input data that is semantically incorrect - /// - `Category::Eof` - unexpected end of the input data - pub fn classify(&self) -> Category { - match self.err.code { - ErrorCode::Message(_) => Category::Data, - ErrorCode::Io(_) => Category::Io, - ErrorCode::EofWhileParsingList - | ErrorCode::EofWhileParsingObject - | ErrorCode::EofWhileParsingString - | ErrorCode::EofWhileParsingValue => Category::Eof, - ErrorCode::ExpectedColon - | ErrorCode::ExpectedListCommaOrEnd - | ErrorCode::ExpectedObjectCommaOrEnd - | ErrorCode::ExpectedSomeIdent - | ErrorCode::ExpectedSomeValue - | ErrorCode::InvalidEscape - | ErrorCode::InvalidNumber - | ErrorCode::NumberOutOfRange - | ErrorCode::InvalidUnicodeCodePoint - | ErrorCode::ControlCharacterWhileParsingString - | ErrorCode::KeyMustBeAString - | ErrorCode::LoneLeadingSurrogateInHexEscape - | ErrorCode::TrailingComma - | ErrorCode::TrailingCharacters - | ErrorCode::UnexpectedEndOfHexEscape - | ErrorCode::RecursionLimitExceeded => Category::Syntax, - } - } - - /// Returns true if this error was caused by a failure to read or write - /// bytes on an IO stream. - pub fn is_io(&self) -> bool { - self.classify() == Category::Io - } - - /// Returns true if this error was caused by input that was not - /// syntactically valid JSON. - pub fn is_syntax(&self) -> bool { - self.classify() == Category::Syntax - } - - /// Returns true if this error was caused by input data that was - /// semantically incorrect. - /// - /// For example, JSON containing a number is semantically incorrect when the - /// type being deserialized into holds a String. - pub fn is_data(&self) -> bool { - self.classify() == Category::Data - } - - /// Returns true if this error was caused by prematurely reaching the end of - /// the input data. - /// - /// Callers that process streaming input may be interested in retrying the - /// deserialization once more data is available. - pub fn is_eof(&self) -> bool { - self.classify() == Category::Eof - } -} - -/// Categorizes the cause of a `serde_json::Error`. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum Category { - /// The error was caused by a failure to read or write bytes on an IO - /// stream. - Io, - - /// The error was caused by input that was not syntactically valid JSON. - Syntax, - - /// The error was caused by input data that was semantically incorrect. - /// - /// For example, JSON containing a number is semantically incorrect when the - /// type being deserialized into holds a String. - Data, - - /// The error was caused by prematurely reaching the end of the input data. - /// - /// Callers that process streaming input may be interested in retrying the - /// deserialization once more data is available. - Eof, -} - -#[cfg(feature = "std")] -#[allow(clippy::fallible_impl_from)] -impl From for io::Error { - /// Convert a `serde_json::Error` into an `io::Error`. - /// - /// JSON syntax and data errors are turned into `InvalidData` IO errors. - /// EOF errors are turned into `UnexpectedEof` IO errors. - /// - /// ``` - /// use std::io; - /// - /// enum MyError { - /// Io(io::Error), - /// Json(serde_json::Error), - /// } - /// - /// impl From for MyError { - /// fn from(err: serde_json::Error) -> MyError { - /// use serde_json::error::Category; - /// match err.classify() { - /// Category::Io => { - /// MyError::Io(err.into()) - /// } - /// Category::Syntax | Category::Data | Category::Eof => { - /// MyError::Json(err) - /// } - /// } - /// } - /// } - /// ``` - fn from(j: Error) -> Self { - if let ErrorCode::Io(err) = j.err.code { - err - } else { - match j.classify() { - Category::Io => unreachable!(), - Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j), - Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j), - } - } - } -} - -struct ErrorImpl { - code: ErrorCode, - line: usize, - column: usize, -} - -pub(crate) enum ErrorCode { - /// Catchall for syntax error messages - Message(Box), - - /// Some IO error occurred while serializing or deserializing. - Io(io::Error), - - /// EOF while parsing a list. - EofWhileParsingList, - - /// EOF while parsing an object. - EofWhileParsingObject, - - /// EOF while parsing a string. - EofWhileParsingString, - - /// EOF while parsing a JSON value. - EofWhileParsingValue, - - /// Expected this character to be a `':'`. - ExpectedColon, - - /// Expected this character to be either a `','` or a `']'`. - ExpectedListCommaOrEnd, - - /// Expected this character to be either a `','` or a `'}'`. - ExpectedObjectCommaOrEnd, - - /// Expected to parse either a `true`, `false`, or a `null`. - ExpectedSomeIdent, - - /// Expected this character to start a JSON value. - ExpectedSomeValue, - - /// Invalid hex escape code. - InvalidEscape, - - /// Invalid number. - InvalidNumber, - - /// Number is bigger than the maximum value of its type. - NumberOutOfRange, - - /// Invalid unicode code point. - InvalidUnicodeCodePoint, - - /// Control character found while parsing a string. - ControlCharacterWhileParsingString, - - /// Object key is not a string. - KeyMustBeAString, - - /// Lone leading surrogate in hex escape. - LoneLeadingSurrogateInHexEscape, - - /// JSON has a comma after the last value in an array or map. - TrailingComma, - - /// JSON has non-whitespace trailing characters after the value. - TrailingCharacters, - - /// Unexpected end of hex excape. - UnexpectedEndOfHexEscape, - - /// Encountered nesting of JSON maps and arrays more than 128 layers deep. - RecursionLimitExceeded, -} - -impl Error { - #[cold] - pub(crate) fn syntax(code: ErrorCode, line: usize, column: usize) -> Self { - Error { - err: Box::new(ErrorImpl { - code: code, - line: line, - column: column, - }), - } - } - - // Not public API. Should be pub(crate). - // - // Update `eager_json` crate when this function changes. - #[doc(hidden)] - #[cold] - pub fn io(error: io::Error) -> Self { - Error { - err: Box::new(ErrorImpl { - code: ErrorCode::Io(error), - line: 0, - column: 0, - }), - } - } - - #[cold] - pub(crate) fn fix_position(self, f: F) -> Self - where - F: FnOnce(ErrorCode) -> Error, - { - if self.err.line == 0 { - f(self.err.code) - } else { - self - } - } -} - -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), - 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"), - ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"), - ErrorCode::ExpectedColon => f.write_str("expected `:`"), - ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"), - ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"), - ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), - ErrorCode::ExpectedSomeValue => f.write_str("expected value"), - ErrorCode::InvalidEscape => f.write_str("invalid escape"), - ErrorCode::InvalidNumber => f.write_str("invalid number"), - ErrorCode::NumberOutOfRange => f.write_str("number out of range"), - ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"), - ErrorCode::ControlCharacterWhileParsingString => { - f.write_str("control character (\\u0000-\\u001F) found while parsing a string") - } - ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), - ErrorCode::LoneLeadingSurrogateInHexEscape => { - f.write_str("lone leading surrogate in hex escape") - } - ErrorCode::TrailingComma => f.write_str("trailing comma"), - ErrorCode::TrailingCharacters => f.write_str("trailing characters"), - ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"), - ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), - } - } -} - -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), - _ => None, - } - } -} - -impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&*self.err, f) - } -} - -impl Display for ErrorImpl { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.line == 0 { - Display::fmt(&self.code, f) - } else { - write!( - f, - "{} at line {} column {}", - self.code, self.line, self.column - ) - } - } -} - -// Remove two layers of verbosity from the debug representation. Humans often -// end up seeing this representation because it is what unwrap() shows. -impl Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "Error({:?}, line: {}, column: {})", - self.err.code.to_string(), - self.err.line, - self.err.column - ) - } -} - -impl de::Error for Error { - #[cold] - fn custom(msg: T) -> Error { - make_error(msg.to_string()) - } - - #[cold] - fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self { - if let de::Unexpected::Unit = unexp { - Error::custom(format_args!("invalid type: null, expected {}", exp)) - } else { - Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) - } - } -} - -impl ser::Error for Error { - #[cold] - fn custom(msg: T) -> Error { - make_error(msg.to_string()) - } -} - -// Parse our own error message that looks like "{} at line {} column {}" to work -// around erased-serde round-tripping the error through de::Error::custom. -fn make_error(mut msg: String) -> Error { - let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0)); - Error { - err: Box::new(ErrorImpl { - code: ErrorCode::Message(msg.into_boxed_str()), - line: line, - column: column, - }), - } -} - -fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> { - let start_of_suffix = match msg.rfind(" at line ") { - Some(index) => index, - None => return None, - }; - - // Find start and end of line number. - let start_of_line = start_of_suffix + " at line ".len(); - let mut end_of_line = start_of_line; - while starts_with_digit(&msg[end_of_line..]) { - end_of_line += 1; - } - - if !msg[end_of_line..].starts_with(" column ") { - return None; - } - - // Find start and end of column number. - let start_of_column = end_of_line + " column ".len(); - let mut end_of_column = start_of_column; - while starts_with_digit(&msg[end_of_column..]) { - end_of_column += 1; - } - - if end_of_column < msg.len() { - return None; - } - - // Parse numbers. - let line = match usize::from_str(&msg[start_of_line..end_of_line]) { - Ok(line) => line, - Err(_) => return None, - }; - let column = match usize::from_str(&msg[start_of_column..end_of_column]) { - Ok(column) => column, - Err(_) => return None, - }; - - msg.truncate(start_of_suffix); - Some((line, column)) -} - -fn starts_with_digit(slice: &str) -> bool { - match slice.as_bytes().get(0) { - None => false, - Some(&byte) => byte >= b'0' && byte <= b'9', - } -} diff --git a/json/src/features_check/error.rs b/json/src/features_check/error.rs deleted file mode 100644 index 22e58235..00000000 --- a/json/src/features_check/error.rs +++ /dev/null @@ -1 +0,0 @@ -"serde_json requires that either `std` (default) or `alloc` feature is enabled" diff --git a/json/src/features_check/mod.rs b/json/src/features_check/mod.rs deleted file mode 100644 index d12032ce..00000000 --- a/json/src/features_check/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Shows a user-friendly compiler error on incompatible selected features. - -#[allow(unused_macros)] -macro_rules! hide_from_rustfmt { - ($mod:item) => { - $mod - }; -} - -#[cfg(not(any(feature = "std", feature = "alloc")))] -hide_from_rustfmt! { - mod error; -} diff --git a/json/src/io/core.rs b/json/src/io/core.rs deleted file mode 100644 index 97354eb3..00000000 --- a/json/src/io/core.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! Reimplements core logic and types from `std::io` in an `alloc`-friendly -//! fashion. - -use crate::lib::*; - -pub enum ErrorKind { - Other, -} - -// IO errors can never occur in no-std mode. All our no-std IO implementations -// are infallible. -pub struct Error; - -impl Display for Error { - fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - unreachable!() - } -} - -impl Error { - pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error { - Error - } -} - -pub type Result = result::Result; - -pub trait Write { - fn write(&mut self, buf: &[u8]) -> Result; - - fn write_all(&mut self, buf: &[u8]) -> Result<()> { - // All our Write impls in no_std mode always write the whole buffer in - // one call infallibly. - let result = self.write(buf); - debug_assert!(result.is_ok()); - debug_assert_eq!(result.unwrap_or(0), buf.len()); - Ok(()) - } - - fn flush(&mut self) -> Result<()>; -} - -impl Write for &mut W { - #[inline] - fn write(&mut self, buf: &[u8]) -> Result { - (*self).write(buf) - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<()> { - (*self).write_all(buf) - } - - #[inline] - fn flush(&mut self) -> Result<()> { - (*self).flush() - } -} - -impl Write for Vec { - #[inline] - fn write(&mut self, buf: &[u8]) -> Result { - self.extend_from_slice(buf); - Ok(buf.len()) - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> Result<()> { - self.extend_from_slice(buf); - Ok(()) - } - - #[inline] - fn flush(&mut self) -> Result<()> { - Ok(()) - } -} diff --git a/json/src/io/mod.rs b/json/src/io/mod.rs deleted file mode 100644 index 9dee4a06..00000000 --- a/json/src/io/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! A tiny, `no_std`-friendly facade around `std::io`. -//! Reexports types from `std` when available; otherwise reimplements and -//! provides some of the core logic. -//! -//! The main reason that `std::io` hasn't found itself reexported as part of -//! the `core` crate is the `std::io::{Read, Write}` traits' reliance on -//! `std::io::Error`, which may contain internally a heap-allocated `Box` -//! and/or now relying on OS-specific `std::backtrace::Backtrace`. - -pub use self::imp::{Error, ErrorKind, Result, Write}; - -#[cfg(not(feature = "std"))] -#[path = "core.rs"] -mod imp; - -#[cfg(feature = "std")] -use std::io as imp; - -#[cfg(feature = "std")] -pub use std::io::{Bytes, Read}; diff --git a/json/src/iter.rs b/json/src/iter.rs deleted file mode 100644 index 1219f088..00000000 --- a/json/src/iter.rs +++ /dev/null @@ -1,70 +0,0 @@ -use crate::io; - -pub struct LineColIterator { - iter: I, - - /// Index of the current line. Characters in the first line of the input - /// (before the first newline character) are in line 1. - line: usize, - - /// Index of the current column. The first character in the input and any - /// characters immediately following a newline character are in column 1. - /// The column is 0 immediately after a newline character has been read. - col: usize, - - /// Byte offset of the start of the current line. This is the sum of lenghts - /// of all previous lines. Keeping track of things this way allows efficient - /// computation of the current line, column, and byte offset while only - /// updating one of the counters in `next()` in the common case. - start_of_line: usize, -} - -impl LineColIterator -where - I: Iterator>, -{ - pub fn new(iter: I) -> LineColIterator { - LineColIterator { - iter: iter, - line: 1, - col: 0, - start_of_line: 0, - } - } - - pub fn line(&self) -> usize { - self.line - } - - pub fn col(&self) -> usize { - self.col - } - - pub fn byte_offset(&self) -> usize { - self.start_of_line + self.col - } -} - -impl Iterator for LineColIterator -where - I: Iterator>, -{ - type Item = io::Result; - - fn next(&mut self) -> Option> { - match self.iter.next() { - None => None, - Some(Ok(b'\n')) => { - self.start_of_line += self.col + 1; - self.line += 1; - self.col = 0; - Some(Ok(b'\n')) - } - Some(Ok(c)) => { - self.col += 1; - Some(Ok(c)) - } - Some(Err(e)) => Some(Err(e)), - } - } -} diff --git a/json/src/lib.rs b/json/src/lib.rs deleted file mode 100644 index 6fb8070e..00000000 --- a/json/src/lib.rs +++ /dev/null @@ -1,449 +0,0 @@ -//! # Serde JSON -//! -//! JSON is a ubiquitous open-standard format that uses human-readable text to -//! transmit data objects consisting of key-value pairs. -//! -//! ```json -//! { -//! "name": "John Doe", -//! "age": 43, -//! "address": { -//! "street": "10 Downing Street", -//! "city": "London" -//! }, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! } -//! ``` -//! -//! 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. -//! -//! Serde JSON provides efficient, flexible, safe ways of converting data -//! between each of these representations. -//! -//! # Operating on untyped JSON values -//! -//! Any valid JSON data can be manipulated in the following recursive enum -//! representation. This data structure is [`serde_json::Value`][value]. -//! -//! ``` -//! # use serde_json::{Number, Map}; -//! # -//! # #[allow(dead_code)] -//! enum Value { -//! Null, -//! Bool(bool), -//! Number(Number), -//! String(String), -//! Array(Vec), -//! Object(Map), -//! } -//! ``` -//! -//! 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. -//! -//! ``` -//! use serde_json::{Result, Value}; -//! -//! fn untyped_example() -> Result<()> { -//! // Some JSON input data as a &str. Maybe this comes from the user. -//! let data = r#" -//! { -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }"#; -//! -//! // Parse the string of data into serde_json::Value. -//! let v: Value = serde_json::from_str(data)?; -//! -//! // Access parts of the data by indexing with square brackets. -//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); -//! -//! Ok(()) -//! } -//! # -//! # fn main() { -//! # untyped_example().unwrap(); -//! # } -//! ``` -//! -//! The result of square bracket indexing like `v["name"]` is a borrow of the -//! data at that index, so the type is `&Value`. A JSON map can be indexed with -//! string keys, while a JSON array can be indexed with integer keys. If the -//! type of the data is not right for the type with which it is being indexed, -//! or if a map does not contain the key being indexed, or if the index into a -//! vector is out of bounds, the returned element is `Value::Null`. -//! -//! When a `Value` is printed, it is printed as a JSON string. So in the code -//! above, the output looks like `Please call "John Doe" at the number "+44 -//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value` -//! containing a JSON string and its JSON representation is `"John Doe"`. -//! Printing as a plain string 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 -//! -//! 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 implement correctly, for example imagine trying to detect the -//! presence of unrecognized fields in the input data. The compiler is powerless -//! to help you when you make a mistake, for example imagine typoing `v["name"]` -//! as `v["nmae"]` in one of the dozens of places it is used in your code. -//! -//! # Parsing JSON as strongly typed data structures -//! -//! Serde provides a powerful way of mapping JSON data into Rust data structures -//! largely automatically. -//! -//! ``` -//! use serde::{Deserialize, Serialize}; -//! use serde_json::Result; -//! -//! #[derive(Serialize, Deserialize)] -//! struct Person { -//! name: String, -//! age: u8, -//! phones: Vec, -//! } -//! -//! fn typed_example() -> Result<()> { -//! // Some JSON input data as a &str. Maybe this comes from the user. -//! let data = r#" -//! { -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }"#; -//! -//! // Parse the string of data into a Person object. This is exactly the -//! // same function as the one that produced serde_json::Value above, but -//! // now we are asking it for a Person as output. -//! let p: Person = serde_json::from_str(data)?; -//! -//! // Do things just like with any other Rust data structure. -//! println!("Please call {} at the number {}", p.name, p.phones[0]); -//! -//! Ok(()) -//! } -//! # -//! # fn main() { -//! # typed_example().unwrap(); -//! # } -//! ``` -//! -//! 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. -//! -//! Any type that implements Serde's `Deserialize` trait can be deserialized -//! this way. This includes built-in Rust standard library types like `Vec` -//! and `HashMap`, 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` so indexing into it makes sense and produces a `String`. -//! -//! # Constructing JSON values -//! -//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` -//! objects with very natural JSON syntax. -//! -//! ``` -//! use serde_json::json; -//! -//! fn main() { -//! // The type of `john` is `serde_json::Value` -//! let john = json!({ -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }); -//! -//! println!("first phone number: {}", john["phones"][0]); -//! -//! // Convert to a string of JSON and print it out -//! println!("{}", john.to_string()); -//! } -//! ``` -//! -//! 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. -//! -//! ``` -//! # use serde_json::json; -//! # -//! # fn random_phone() -> u16 { 0 } -//! # -//! let full_name = "John Doe"; -//! let age_last_year = 42; -//! -//! // The type of `john` is `serde_json::Value` -//! let john = json!({ -//! "name": full_name, -//! "age": age_last_year + 1, -//! "phones": [ -//! format!("+44 {}", random_phone()) -//! ] -//! }); -//! ``` -//! -//! 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. -//! -//! # Creating JSON by serializing data structures -//! -//! A data structure can be converted to a JSON string by -//! [`serde_json::to_string`][to_string]. There is also -//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec` and -//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` -//! such as a File or a TCP stream. -//! -//! ``` -//! use serde::{Deserialize, Serialize}; -//! use serde_json::Result; -//! -//! #[derive(Serialize, Deserialize)] -//! struct Address { -//! street: String, -//! city: String, -//! } -//! -//! fn print_an_address() -> Result<()> { -//! // Some data structure. -//! let address = Address { -//! street: "10 Downing Street".to_owned(), -//! city: "London".to_owned(), -//! }; -//! -//! // Serialize it to a JSON string. -//! let j = serde_json::to_string(&address)?; -//! -//! // Print, write to a file, or send to an HTTP server. -//! println!("{}", j); -//! -//! Ok(()) -//! } -//! # -//! # fn main() { -//! # print_an_address().unwrap(); -//! # } -//! ``` -//! -//! Any type that implements Serde's `Serialize` trait can be serialized this -//! way. This includes built-in Rust standard library types like `Vec` and -//! `HashMap`, as well as any structs or enums annotated with -//! `#[derive(Serialize)]`. -//! -//! # 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: -//! -//! ```toml -//! [dependencies] -//! serde_json = { version = "1.0", default-features = false, features = ["alloc"] } -//! ``` -//! -//! 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 -//! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ - -#![doc(html_root_url = "https://docs.rs/serde_json/1.0.53")] -#![deny(clippy::all, clippy::pedantic)] -// Ignored clippy lints -#![allow( - clippy::deprecated_cfg_attr, - clippy::doc_markdown, - clippy::match_single_binding, - clippy::needless_doctest_main, - clippy::transmute_ptr_to_ptr -)] -// Ignored clippy_pedantic lints -#![allow( - // Deserializer::from_str, into_iter - clippy::should_implement_trait, - // integer and float ser/de requires these sorts of casts - clippy::cast_possible_wrap, - clippy::cast_precision_loss, - clippy::cast_sign_loss, - // correctly used - clippy::enum_glob_use, - clippy::integer_division, - clippy::wildcard_imports, - // things are often more readable this way - clippy::cast_lossless, - clippy::module_name_repetitions, - clippy::shadow_unrelated, - clippy::single_match_else, - clippy::too_many_lines, - clippy::use_self, - clippy::zero_prefixed_literal, - // we support older compilers - clippy::checked_conversions, - clippy::redundant_field_names, - // noisy - clippy::missing_errors_doc, - clippy::must_use_candidate, -)] -#![allow(non_upper_case_globals)] -#![deny(missing_docs)] -#![cfg_attr(not(feature = "std"), no_std)] - -//////////////////////////////////////////////////////////////////////////////// - -#[cfg(not(feature = "std"))] -extern crate alloc; - -/// A facade around all the types we need from the `std`, `core`, and `alloc` -/// crates. This avoids elaborate import wrangling having to happen in every -/// module. -mod lib { - mod core { - #[cfg(not(feature = "std"))] - pub use core::*; - #[cfg(feature = "std")] - pub use std::*; - } - - pub use self::core::cell::{Cell, RefCell}; - pub use self::core::clone::{self, Clone}; - pub use self::core::convert::{self, From, Into}; - pub use self::core::default::{self, Default}; - pub use self::core::fmt::{self, Debug, Display}; - pub use self::core::hash::{self, Hash}; - pub use self::core::iter::FusedIterator; - pub use self::core::marker::{self, PhantomData}; - pub use self::core::result::{self, Result}; - pub use self::core::{borrow, char, cmp, iter, mem, num, ops, slice, str}; - - #[cfg(not(feature = "std"))] - pub use alloc::borrow::{Cow, ToOwned}; - #[cfg(feature = "std")] - pub use std::borrow::{Cow, ToOwned}; - - #[cfg(not(feature = "std"))] - pub use alloc::string::{String, ToString}; - #[cfg(feature = "std")] - pub use std::string::{String, ToString}; - - #[cfg(not(feature = "std"))] - pub use alloc::vec::{self, Vec}; - #[cfg(feature = "std")] - pub use std::vec::{self, Vec}; - - #[cfg(not(feature = "std"))] - pub use alloc::boxed::Box; - #[cfg(feature = "std")] - pub use std::boxed::Box; - - #[cfg(not(feature = "std"))] - pub use alloc::collections::{btree_map, BTreeMap}; - #[cfg(feature = "std")] - pub use std::collections::{btree_map, BTreeMap}; - - #[cfg(feature = "std")] - pub use std::error; -} - -//////////////////////////////////////////////////////////////////////////////// - -#[cfg(feature = "std")] -#[doc(inline)] -pub use crate::de::from_reader; -#[doc(inline)] -pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer}; -#[doc(inline)] -pub use crate::error::{Error, Result}; -#[doc(inline)] -pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; -#[cfg(feature = "std")] -#[doc(inline)] -pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; -#[doc(inline)] -pub use crate::value::{from_value, to_value, Map, Number, Value}; - -// We only use our own error type; no need for From conversions provided by the -// standard library's try! macro. This reduces lines of LLVM IR by 4%. -macro_rules! tri { - ($e:expr) => { - match $e { - crate::lib::Result::Ok(val) => val, - crate::lib::Result::Err(err) => return crate::lib::Result::Err(err), - } - }; -} - -#[macro_use] -mod macros; - -pub mod de; -pub mod error; -pub mod map; -#[cfg(feature = "std")] -pub mod ser; -#[cfg(not(feature = "std"))] -mod ser; -pub mod value; - -mod features_check; - -mod io; -#[cfg(feature = "std")] -mod iter; -mod number; -mod read; - -#[cfg(feature = "raw_value")] -mod raw; diff --git a/json/src/macros.rs b/json/src/macros.rs deleted file mode 100644 index 9ab58b13..00000000 --- a/json/src/macros.rs +++ /dev/null @@ -1,292 +0,0 @@ -/// Construct a `serde_json::Value` from a JSON literal. -/// -/// ``` -/// # use serde_json::json; -/// # -/// let value = json!({ -/// "code": 200, -/// "success": true, -/// "payload": { -/// "features": [ -/// "serde", -/// "json" -/// ] -/// } -/// }); -/// ``` -/// -/// Variables or expressions can be interpolated into the JSON literal. Any type -/// interpolated into an array element or object value must implement Serde's -/// `Serialize` trait, while any type interpolated into a object key must -/// implement `Into`. If the `Serialize` implementation of the -/// interpolated type decides to fail, or if the interpolated type contains a -/// map with non-string keys, the `json!` macro will panic. -/// -/// ``` -/// # use serde_json::json; -/// # -/// let code = 200; -/// let features = vec!["serde", "json"]; -/// -/// let value = json!({ -/// "code": code, -/// "success": code == 200, -/// "payload": { -/// features[0]: features[1] -/// } -/// }); -/// ``` -/// -/// Trailing commas are allowed inside both arrays and objects. -/// -/// ``` -/// # use serde_json::json; -/// # -/// let value = json!([ -/// "notice", -/// "the", -/// "trailing", -/// "comma -->", -/// ]); -/// ``` -#[macro_export(local_inner_macros)] -macro_rules! json { - // Hide distracting implementation details from the generated rustdoc. - ($($json:tt)+) => { - json_internal!($($json)+) - }; -} - -// Rocket relies on this because they export their own `json!` with a different -// doc comment than ours, and various Rust bugs prevent them from calling our -// `json!` from their `json!` so they call `json_internal!` directly. Check with -// @SergioBenitez before making breaking changes to this macro. -// -// Changes are fine as long as `json_internal!` does not call any new helper -// macros and can still be invoked as `json_internal!($($json)+)`. -#[macro_export(local_inner_macros)] -#[doc(hidden)] -macro_rules! json_internal { - ////////////////////////////////////////////////////////////////////////// - // TT muncher for parsing the inside of an array [...]. Produces a vec![...] - // of the elements. - // - // Must be invoked as: json_internal!(@array [] $($tt)*) - ////////////////////////////////////////////////////////////////////////// - - // Done with trailing comma. - (@array [$($elems:expr,)*]) => { - json_internal_vec![$($elems,)*] - }; - - // Done without trailing comma. - (@array [$($elems:expr),*]) => { - json_internal_vec![$($elems),*] - }; - - // Next element is `null`. - (@array [$($elems:expr,)*] null $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*) - }; - - // Next element is `true`. - (@array [$($elems:expr,)*] true $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*) - }; - - // Next element is `false`. - (@array [$($elems:expr,)*] false $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*) - }; - - // Next element is an array. - (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*) - }; - - // Next element is a map. - (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*) - }; - - // Next element is an expression followed by comma. - (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { - json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*) - }; - - // Last element is an expression with no trailing comma. - (@array [$($elems:expr,)*] $last:expr) => { - json_internal!(@array [$($elems,)* json_internal!($last)]) - }; - - // Comma after the most recent element. - (@array [$($elems:expr),*] , $($rest:tt)*) => { - json_internal!(@array [$($elems,)*] $($rest)*) - }; - - // Unexpected token after most recent element. - (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { - json_unexpected!($unexpected) - }; - - ////////////////////////////////////////////////////////////////////////// - // TT muncher for parsing the inside of an object {...}. Each entry is - // inserted into the given map variable. - // - // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) - // - // We require two copies of the input tokens so that we can match on one - // copy and trigger errors on the other copy. - ////////////////////////////////////////////////////////////////////////// - - // Done. - (@object $object:ident () () ()) => {}; - - // Insert the current entry followed by trailing comma. - (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { - let _ = $object.insert(($($key)+).into(), $value); - json_internal!(@object $object () ($($rest)*) ($($rest)*)); - }; - - // Current entry followed by unexpected token. - (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { - json_unexpected!($unexpected); - }; - - // Insert the last entry without trailing comma. - (@object $object:ident [$($key:tt)+] ($value:expr)) => { - let _ = $object.insert(($($key)+).into(), $value); - }; - - // Next value is `null`. - (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*); - }; - - // Next value is `true`. - (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*); - }; - - // Next value is `false`. - (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*); - }; - - // Next value is an array. - (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*); - }; - - // Next value is a map. - (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*); - }; - - // Next value is an expression followed by comma. - (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*); - }; - - // Last value is an expression with no trailing comma. - (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { - json_internal!(@object $object [$($key)+] (json_internal!($value))); - }; - - // Missing value for last entry. Trigger a reasonable error message. - (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { - // "unexpected end of macro invocation" - json_internal!(); - }; - - // Missing colon and value for last entry. Trigger a reasonable error - // message. - (@object $object:ident ($($key:tt)+) () $copy:tt) => { - // "unexpected end of macro invocation" - json_internal!(); - }; - - // Misplaced colon. Trigger a reasonable error message. - (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { - // Takes no arguments so "no rules expected the token `:`". - json_unexpected!($colon); - }; - - // Found a comma inside a key. Trigger a reasonable error message. - (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { - // Takes no arguments so "no rules expected the token `,`". - json_unexpected!($comma); - }; - - // Key is fully parenthesized. This avoids clippy double_parens false - // positives because the parenthesization may be necessary here. - (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); - }; - - // Munch a token into the current key. - (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { - json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); - }; - - ////////////////////////////////////////////////////////////////////////// - // The main implementation. - // - // Must be invoked as: json_internal!($($json)+) - ////////////////////////////////////////////////////////////////////////// - - (null) => { - $crate::Value::Null - }; - - (true) => { - $crate::Value::Bool(true) - }; - - (false) => { - $crate::Value::Bool(false) - }; - - ([]) => { - $crate::Value::Array(json_internal_vec![]) - }; - - ([ $($tt:tt)+ ]) => { - $crate::Value::Array(json_internal!(@array [] $($tt)+)) - }; - - ({}) => { - $crate::Value::Object($crate::Map::new()) - }; - - ({ $($tt:tt)+ }) => { - $crate::Value::Object({ - let mut object = $crate::Map::new(); - json_internal!(@object object () ($($tt)+) ($($tt)+)); - object - }) - }; - - // Any Serialize type: numbers, strings, struct literals, variables etc. - // Must be below every other rule. - ($other:expr) => { - $crate::to_value(&$other).unwrap() - }; -} - -// The json_internal macro above cannot invoke vec directly because it uses -// local_inner_macros. A vec invocation there would resolve to $crate::vec. -// Instead invoke vec here outside of local_inner_macros. -#[macro_export] -#[doc(hidden)] -macro_rules! json_internal_vec { - ($($content:tt)*) => { - vec![$($content)*] - }; -} - -#[macro_export] -#[doc(hidden)] -macro_rules! json_unexpected { - () => {}; -} diff --git a/json/src/map.rs b/json/src/map.rs deleted file mode 100644 index 449c453b..00000000 --- a/json/src/map.rs +++ /dev/null @@ -1,822 +0,0 @@ -//! A map of String to serde_json::Value. -//! -//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order` -//! feature of serde_json to use [`IndexMap`] instead. -//! -//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html -//! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html - -use crate::lib::borrow::Borrow; -use crate::lib::iter::FromIterator; -use crate::lib::*; -use crate::value::Value; -use serde::de; - -#[cfg(feature = "preserve_order")] -use indexmap::{self, IndexMap}; - -/// Represents a JSON key/value type. -pub struct Map { - map: MapImpl, -} - -#[cfg(not(feature = "preserve_order"))] -type MapImpl = BTreeMap; -#[cfg(feature = "preserve_order")] -type MapImpl = IndexMap; - -impl Map { - /// Makes a new empty Map. - #[inline] - pub fn new() -> Self { - Map { - map: MapImpl::new(), - } - } - - #[cfg(not(feature = "preserve_order"))] - /// Makes a new empty Map with the given initial capacity. - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - // does not support with_capacity - let _ = capacity; - Map { - map: BTreeMap::new(), - } - } - - #[cfg(feature = "preserve_order")] - /// Makes a new empty Map with the given initial capacity. - #[inline] - pub fn with_capacity(capacity: usize) -> Self { - Map { - map: IndexMap::with_capacity(capacity), - } - } - - /// Clears the map, removing all values. - #[inline] - pub fn clear(&mut self) { - self.map.clear() - } - - /// Returns a reference to the value corresponding to the key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - #[inline] - pub fn get(&self, key: &Q) -> Option<&Value> - where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, - { - self.map.get(key) - } - - /// Returns true if the map contains a value for the specified key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - #[inline] - pub fn contains_key(&self, key: &Q) -> bool - where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, - { - self.map.contains_key(key) - } - - /// Returns a mutable reference to the value corresponding to the key. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - #[inline] - pub fn get_mut(&mut self, key: &Q) -> Option<&mut Value> - where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, - { - self.map.get_mut(key) - } - - /// Inserts a key-value pair into the map. - /// - /// If the map did not have this key present, `None` is returned. - /// - /// If the map did have this key present, the value is updated, and the old - /// value is returned. - #[inline] - pub fn insert(&mut self, k: String, v: Value) -> Option { - self.map.insert(k, v) - } - - /// Removes a key from the map, returning the value at the key if the key - /// was previously in the map. - /// - /// The key may be any borrowed form of the map's key type, but the ordering - /// on the borrowed form *must* match the ordering on the key type. - #[inline] - pub fn remove(&mut self, key: &Q) -> Option - where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, - { - #[cfg(feature = "preserve_order")] - return self.map.swap_remove(key); - #[cfg(not(feature = "preserve_order"))] - return self.map.remove(key); - } - - /// 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 std::mem::replace(&mut other.map, MapImpl::default()).into_iter() { - self.map.insert(k, v); - } - #[cfg(not(feature = "preserve_order"))] - self.map.append(&mut other.map); - } - - /// Gets the given key's corresponding entry in the map for in-place - /// manipulation. - pub fn entry(&mut self, key: S) -> Entry - where - S: Into, - { - #[cfg(not(feature = "preserve_order"))] - use crate::lib::btree_map::Entry as EntryImpl; - #[cfg(feature = "preserve_order")] - use indexmap::map::Entry as EntryImpl; - - match self.map.entry(key.into()) { - EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }), - EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied: occupied }), - } - } - - /// Returns the number of elements in the map. - #[inline] - pub fn len(&self) -> usize { - self.map.len() - } - - /// Returns true if the map contains no elements. - #[inline] - pub fn is_empty(&self) -> bool { - self.map.is_empty() - } - - /// Gets an iterator over the entries of the map. - #[inline] - pub fn iter(&self) -> Iter { - Iter { - iter: self.map.iter(), - } - } - - /// Gets a mutable iterator over the entries of the map. - #[inline] - pub fn iter_mut(&mut self) -> IterMut { - IterMut { - iter: self.map.iter_mut(), - } - } - - /// Gets an iterator over the keys of the map. - #[inline] - pub fn keys(&self) -> Keys { - Keys { - iter: self.map.keys(), - } - } - - /// Gets an iterator over the values of the map. - #[inline] - pub fn values(&self) -> Values { - Values { - iter: self.map.values(), - } - } - - /// Gets an iterator over mutable values of the map. - #[inline] - pub fn values_mut(&mut self) -> ValuesMut { - ValuesMut { - iter: self.map.values_mut(), - } - } -} - -impl Default for Map { - #[inline] - fn default() -> Self { - Map { - map: MapImpl::new(), - } - } -} - -impl Clone for Map { - #[inline] - fn clone(&self) -> Self { - Map { - map: self.map.clone(), - } - } -} - -impl PartialEq for Map { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.map.eq(&other.map) - } -} - -impl Eq for Map {} - -/// Access an element of this map. Panics if the given key is not present in the -/// map. -/// -/// ``` -/// # use serde_json::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(), -/// _ => None, -/// } -/// # ; -/// ``` -impl<'a, Q> ops::Index<&'a Q> for Map -where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, -{ - type Output = Value; - - fn index(&self, index: &Q) -> &Value { - self.map.index(index) - } -} - -/// Mutably access an element of this map. Panics if the given key is not -/// present in the map. -/// -/// ``` -/// # use serde_json::json; -/// # -/// # let mut map = serde_json::Map::new(); -/// # map.insert("key".to_owned(), serde_json::Value::Null); -/// # -/// map["key"] = json!("value"); -/// ``` -impl<'a, Q> ops::IndexMut<&'a Q> for Map -where - String: Borrow, - Q: ?Sized + Ord + Eq + Hash, -{ - fn index_mut(&mut self, index: &Q) -> &mut Value { - self.map.get_mut(index).expect("no entry found for key") - } -} - -impl Debug for Map { - #[inline] - fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { - self.map.fmt(formatter) - } -} - -#[cfg(any(feature = "std", feature = "alloc"))] -impl serde::ser::Serialize for Map { - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: serde::ser::Serializer, - { - use serde::ser::SerializeMap; - let mut map = tri!(serializer.serialize_map(Some(self.len()))); - for (k, v) in self { - tri!(map.serialize_entry(k, v)); - } - map.end() - } -} - -impl<'de> de::Deserialize<'de> for Map { - #[inline] - fn deserialize(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - struct Visitor; - - impl<'de> de::Visitor<'de> for Visitor { - type Value = Map; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a map") - } - - #[inline] - fn visit_unit(self) -> Result - where - E: de::Error, - { - Ok(Map::new()) - } - - #[cfg(any(feature = "std", feature = "alloc"))] - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where - V: de::MapAccess<'de>, - { - let mut values = Map::new(); - - while let Some((key, value)) = tri!(visitor.next_entry()) { - values.insert(key, value); - } - - Ok(values) - } - } - - deserializer.deserialize_map(Visitor) - } -} - -impl FromIterator<(String, Value)> for Map { - fn from_iter(iter: T) -> Self - where - T: IntoIterator, - { - Map { - map: FromIterator::from_iter(iter), - } - } -} - -impl Extend<(String, Value)> for Map { - fn extend(&mut self, iter: T) - where - T: IntoIterator, - { - self.map.extend(iter); - } -} - -macro_rules! delegate_iterator { - (($name:ident $($generics:tt)*) => $item:ty) => { - impl $($generics)* Iterator for $name $($generics)* { - type Item = $item; - #[inline] - fn next(&mut self) -> Option { - self.iter.next() - } - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - } - - impl $($generics)* DoubleEndedIterator for $name $($generics)* { - #[inline] - fn next_back(&mut self) -> Option { - self.iter.next_back() - } - } - - impl $($generics)* ExactSizeIterator for $name $($generics)* { - #[inline] - fn len(&self) -> usize { - self.iter.len() - } - } - - impl $($generics)* FusedIterator for $name $($generics)* {} - } -} - -////////////////////////////////////////////////////////////////////////////// - -/// A view into a single entry in a map, which may either be vacant or occupied. -/// This enum is constructed from the [`entry`] method on [`Map`]. -/// -/// [`entry`]: struct.Map.html#method.entry -/// [`Map`]: struct.Map.html -pub enum Entry<'a> { - /// A vacant Entry. - Vacant(VacantEntry<'a>), - /// An occupied Entry. - Occupied(OccupiedEntry<'a>), -} - -/// A vacant Entry. It is part of the [`Entry`] enum. -/// -/// [`Entry`]: enum.Entry.html -pub struct VacantEntry<'a> { - vacant: VacantEntryImpl<'a>, -} - -/// An occupied Entry. It is part of the [`Entry`] enum. -/// -/// [`Entry`]: enum.Entry.html -pub struct OccupiedEntry<'a> { - occupied: OccupiedEntryImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>; - -#[cfg(not(feature = "preserve_order"))] -type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>; - -impl<'a> Entry<'a> { - /// Returns a reference to this entry's key. - /// - /// # Examples - /// - /// ``` - /// let mut map = serde_json::Map::new(); - /// 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(), - } - } - - /// Ensures a value is in the entry by inserting the default if empty, and - /// returns a mutable reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut map = serde_json::Map::new(); - /// map.entry("serde").or_insert(json!(12)); - /// - /// assert_eq!(map["serde"], 12); - /// ``` - pub fn or_insert(self, default: Value) -> &'a mut Value { - match self { - Entry::Vacant(entry) => entry.insert(default), - Entry::Occupied(entry) => entry.into_mut(), - } - } - - /// Ensures a value is in the entry by inserting the result of the default - /// function if empty, and returns a mutable reference to the value in the - /// entry. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut map = serde_json::Map::new(); - /// map.entry("serde").or_insert_with(|| json!("hoho")); - /// - /// assert_eq!(map["serde"], "hoho".to_owned()); - /// ``` - pub fn or_insert_with(self, default: F) -> &'a mut Value - where - F: FnOnce() -> Value, - { - match self { - Entry::Vacant(entry) => entry.insert(default()), - Entry::Occupied(entry) => entry.into_mut(), - } - } -} - -impl<'a> VacantEntry<'a> { - /// Gets a reference to the key that would be used when inserting a value - /// through the VacantEntry. - /// - /// # Examples - /// - /// ``` - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// - /// match map.entry("serde") { - /// Entry::Vacant(vacant) => { - /// assert_eq!(vacant.key(), &"serde"); - /// } - /// Entry::Occupied(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn key(&self) -> &String { - self.vacant.key() - } - - /// Sets the value of the entry with the VacantEntry's key, and returns a - /// mutable reference to it. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// - /// match map.entry("serde") { - /// Entry::Vacant(vacant) => { - /// vacant.insert(json!("hoho")); - /// } - /// Entry::Occupied(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn insert(self, value: Value) -> &'a mut Value { - self.vacant.insert(value) - } -} - -impl<'a> OccupiedEntry<'a> { - /// Gets a reference to the key in the entry. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!(12)); - /// - /// match map.entry("serde") { - /// Entry::Occupied(occupied) => { - /// assert_eq!(occupied.key(), &"serde"); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn key(&self) -> &String { - self.occupied.key() - } - - /// Gets a reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!(12)); - /// - /// match map.entry("serde") { - /// Entry::Occupied(occupied) => { - /// assert_eq!(occupied.get(), 12); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn get(&self) -> &Value { - self.occupied.get() - } - - /// Gets a mutable reference to the value in the entry. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!([1, 2, 3])); - /// - /// match map.entry("serde") { - /// Entry::Occupied(mut occupied) => { - /// occupied.get_mut().as_array_mut().unwrap().push(json!(4)); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// - /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); - /// ``` - #[inline] - pub fn get_mut(&mut self) -> &mut Value { - self.occupied.get_mut() - } - - /// Converts the entry into a mutable reference to its value. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!([1, 2, 3])); - /// - /// match map.entry("serde") { - /// Entry::Occupied(mut occupied) => { - /// occupied.into_mut().as_array_mut().unwrap().push(json!(4)); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// - /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); - /// ``` - #[inline] - pub fn into_mut(self) -> &'a mut Value { - self.occupied.into_mut() - } - - /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns - /// the entry's old value. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!(12)); - /// - /// match map.entry("serde") { - /// Entry::Occupied(mut occupied) => { - /// assert_eq!(occupied.insert(json!(13)), 12); - /// assert_eq!(occupied.get(), 13); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn insert(&mut self, value: Value) -> Value { - self.occupied.insert(value) - } - - /// Takes the value of the entry out of the map, and returns it. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// use serde_json::map::Entry; - /// - /// let mut map = serde_json::Map::new(); - /// map.insert("serde".to_owned(), json!(12)); - /// - /// match map.entry("serde") { - /// Entry::Occupied(occupied) => { - /// assert_eq!(occupied.remove(), 12); - /// } - /// Entry::Vacant(_) => unimplemented!(), - /// } - /// ``` - #[inline] - pub fn remove(self) -> Value { - #[cfg(feature = "preserve_order")] - return self.occupied.swap_remove(); - #[cfg(not(feature = "preserve_order"))] - return self.occupied.remove(); - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl<'a> IntoIterator for &'a Map { - type Item = (&'a String, &'a Value); - type IntoIter = Iter<'a>; - #[inline] - fn into_iter(self) -> Self::IntoIter { - Iter { - iter: self.map.iter(), - } - } -} - -/// An iterator over a serde_json::Map's entries. -pub struct Iter<'a> { - iter: IterImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type IterImpl<'a> = btree_map::Iter<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; - -delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); - -////////////////////////////////////////////////////////////////////////////// - -impl<'a> IntoIterator for &'a mut Map { - type Item = (&'a String, &'a mut Value); - type IntoIter = IterMut<'a>; - #[inline] - fn into_iter(self) -> Self::IntoIter { - IterMut { - iter: self.map.iter_mut(), - } - } -} - -/// A mutable iterator over a serde_json::Map's entries. -pub struct IterMut<'a> { - iter: IterMutImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; - -delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); - -////////////////////////////////////////////////////////////////////////////// - -impl IntoIterator for Map { - type Item = (String, Value); - type IntoIter = IntoIter; - #[inline] - fn into_iter(self) -> Self::IntoIter { - IntoIter { - iter: self.map.into_iter(), - } - } -} - -/// An owning iterator over a serde_json::Map's entries. -pub struct IntoIter { - iter: IntoIterImpl, -} - -#[cfg(not(feature = "preserve_order"))] -type IntoIterImpl = btree_map::IntoIter; -#[cfg(feature = "preserve_order")] -type IntoIterImpl = indexmap::map::IntoIter; - -delegate_iterator!((IntoIter) => (String, Value)); - -////////////////////////////////////////////////////////////////////////////// - -/// An iterator over a serde_json::Map's keys. -pub struct Keys<'a> { - iter: KeysImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; - -delegate_iterator!((Keys<'a>) => &'a String); - -////////////////////////////////////////////////////////////////////////////// - -/// An iterator over a serde_json::Map's values. -pub struct Values<'a> { - iter: ValuesImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; - -delegate_iterator!((Values<'a>) => &'a Value); - -////////////////////////////////////////////////////////////////////////////// - -/// A mutable iterator over a serde_json::Map's values. -pub struct ValuesMut<'a> { - iter: ValuesMutImpl<'a>, -} - -#[cfg(not(feature = "preserve_order"))] -type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; -#[cfg(feature = "preserve_order")] -type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; - -delegate_iterator!((ValuesMut<'a>) => &'a mut Value); diff --git a/json/src/number.rs b/json/src/number.rs deleted file mode 100644 index 77a715fa..00000000 --- a/json/src/number.rs +++ /dev/null @@ -1,749 +0,0 @@ -use crate::de::ParserNumber; -use crate::error::Error; -use crate::lib::*; -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}; - -#[cfg(feature = "arbitrary_precision")] -pub(crate) const TOKEN: &str = "$serde_json::private::Number"; - -/// Represents a JSON number, whether integer or floating point. -#[repr(transparent)] -#[derive(Clone, Eq, PartialEq)] -pub struct Number { - n: N, -} - -#[cfg(not(feature = "arbitrary_precision"))] -#[derive(Copy, Clone, PartialEq)] -enum N { - PosInt(u64), - /// Always less than zero. - NegInt(i64), - /// Always finite. - Float(f64), -} - -// Implementing Eq is fine since any float values are always finite. -#[cfg(not(feature = "arbitrary_precision"))] -impl Eq for N {} - -#[cfg(feature = "arbitrary_precision")] -type N = String; - -impl Number { - /// Returns true if the `Number` is an integer between `i64::MIN` and - /// `i64::MAX`. - /// - /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to - /// return the integer value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let big = i64::max_value() as u64 + 10; - /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); - /// - /// assert!(v["a"].is_i64()); - /// - /// // Greater than i64::MAX. - /// assert!(!v["b"].is_i64()); - /// - /// // Numbers with a decimal point are not considered integers. - /// assert!(!v["c"].is_i64()); - /// ``` - #[inline] - pub fn is_i64(&self) -> bool { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::PosInt(v) => v <= i64::max_value() as u64, - N::NegInt(_) => true, - N::Float(_) => false, - } - #[cfg(feature = "arbitrary_precision")] - self.as_i64().is_some() - } - - /// Returns true if the `Number` is an integer between zero and `u64::MAX`. - /// - /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to - /// return the integer value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); - /// - /// assert!(v["a"].is_u64()); - /// - /// // Negative integer. - /// assert!(!v["b"].is_u64()); - /// - /// // Numbers with a decimal point are not considered integers. - /// assert!(!v["c"].is_u64()); - /// ``` - #[inline] - pub fn is_u64(&self) -> bool { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::PosInt(_) => true, - N::NegInt(_) | N::Float(_) => false, - } - #[cfg(feature = "arbitrary_precision")] - self.as_u64().is_some() - } - - /// Returns true if the `Number` can be represented by f64. - /// - /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to - /// return the floating point value. - /// - /// Currently this function returns true if and only if both `is_i64` and - /// `is_u64` return false but this is not a guarantee in the future. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); - /// - /// assert!(v["a"].is_f64()); - /// - /// // Integers. - /// assert!(!v["b"].is_f64()); - /// assert!(!v["c"].is_f64()); - /// ``` - #[inline] - pub fn is_f64(&self) -> bool { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::Float(_) => true, - N::PosInt(_) | N::NegInt(_) => false, - } - #[cfg(feature = "arbitrary_precision")] - { - for c in self.n.chars() { - if c == '.' || c == 'e' || c == 'E' { - return self.n.parse::().ok().map_or(false, |f| f.is_finite()); - } - } - false - } - } - - /// If the `Number` is an integer, represent it as i64 if possible. Returns - /// None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let big = i64::max_value() as u64 + 10; - /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); - /// - /// assert_eq!(v["a"].as_i64(), Some(64)); - /// assert_eq!(v["b"].as_i64(), None); - /// assert_eq!(v["c"].as_i64(), None); - /// ``` - #[inline] - pub fn as_i64(&self) -> Option { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::PosInt(n) => { - if n <= i64::max_value() as u64 { - Some(n as i64) - } else { - None - } - } - N::NegInt(n) => Some(n), - N::Float(_) => None, - } - #[cfg(feature = "arbitrary_precision")] - self.n.parse().ok() - } - - /// If the `Number` is an integer, represent it as u64 if possible. Returns - /// None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); - /// - /// assert_eq!(v["a"].as_u64(), Some(64)); - /// assert_eq!(v["b"].as_u64(), None); - /// assert_eq!(v["c"].as_u64(), None); - /// ``` - #[inline] - pub fn as_u64(&self) -> Option { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::PosInt(n) => Some(n), - N::NegInt(_) | N::Float(_) => None, - } - #[cfg(feature = "arbitrary_precision")] - self.n.parse().ok() - } - - /// Represents the number as f64 if possible. Returns None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); - /// - /// assert_eq!(v["a"].as_f64(), Some(256.0)); - /// assert_eq!(v["b"].as_f64(), Some(64.0)); - /// assert_eq!(v["c"].as_f64(), Some(-64.0)); - /// ``` - #[inline] - pub fn as_f64(&self) -> Option { - #[cfg(not(feature = "arbitrary_precision"))] - match self.n { - N::PosInt(n) => Some(n as f64), - N::NegInt(n) => Some(n as f64), - N::Float(n) => Some(n), - } - #[cfg(feature = "arbitrary_precision")] - self.n.parse().ok() - } - - /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON - /// numbers. - /// - /// ``` - /// # use std::f64; - /// # - /// # use serde_json::Number; - /// # - /// assert!(Number::from_f64(256.0).is_some()); - /// - /// assert!(Number::from_f64(f64::NAN).is_none()); - /// ``` - #[inline] - pub fn from_f64(f: f64) -> Option { - if f.is_finite() { - let n = { - #[cfg(not(feature = "arbitrary_precision"))] - { - N::Float(f) - } - #[cfg(feature = "arbitrary_precision")] - { - ryu::Buffer::new().format_finite(f).to_owned() - } - }; - Some(Number { n: n }) - } else { - None - } - } - - #[cfg(feature = "arbitrary_precision")] - /// Not public API. Only tests use this. - #[doc(hidden)] - #[inline] - pub fn from_string_unchecked(n: String) -> Self { - Number { n: n } - } -} - -impl fmt::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), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(&self.n, formatter) - } -} - -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() - } -} - -impl Serialize for Number { - #[cfg(not(feature = "arbitrary_precision"))] - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self.n { - N::PosInt(u) => serializer.serialize_u64(u), - N::NegInt(i) => serializer.serialize_i64(i), - N::Float(f) => serializer.serialize_f64(f), - } - } - - #[cfg(feature = "arbitrary_precision")] - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - use serde::ser::SerializeStruct; - - let mut s = serializer.serialize_struct(TOKEN, 1)?; - s.serialize_field(TOKEN, &self.n)?; - s.end() - } -} - -impl<'de> Deserialize<'de> for Number { - #[inline] - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct NumberVisitor; - - impl<'de> Visitor<'de> for NumberVisitor { - type Value = Number; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a JSON number") - } - - #[inline] - fn visit_i64(self, value: i64) -> Result { - Ok(value.into()) - } - - #[inline] - fn visit_u64(self, value: u64) -> Result { - Ok(value.into()) - } - - #[inline] - fn visit_f64(self, value: f64) -> Result - where - E: de::Error, - { - Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number")) - } - - #[cfg(feature = "arbitrary_precision")] - #[inline] - fn visit_map(self, mut visitor: V) -> Result - where - V: de::MapAccess<'de>, - { - let value = visitor.next_key::()?; - if value.is_none() { - return Err(de::Error::invalid_type(Unexpected::Map, &self)); - } - let v: NumberFromString = visitor.next_value()?; - Ok(v.value) - } - } - - deserializer.deserialize_any(NumberVisitor) - } -} - -#[cfg(feature = "arbitrary_precision")] -struct NumberKey; - -#[cfg(feature = "arbitrary_precision")] -impl<'de> de::Deserialize<'de> for NumberKey { - fn deserialize(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - struct FieldVisitor; - - impl<'de> de::Visitor<'de> for FieldVisitor { - type Value = (); - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a valid number field") - } - - fn visit_str(self, s: &str) -> Result<(), E> - where - E: de::Error, - { - if s == TOKEN { - Ok(()) - } else { - Err(de::Error::custom("expected field with custom name")) - } - } - } - - deserializer.deserialize_identifier(FieldVisitor)?; - Ok(NumberKey) - } -} - -#[cfg(feature = "arbitrary_precision")] -pub struct NumberFromString { - pub value: Number, -} - -#[cfg(feature = "arbitrary_precision")] -impl<'de> de::Deserialize<'de> for NumberFromString { - fn deserialize(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - struct Visitor; - - impl<'de> de::Visitor<'de> for Visitor { - type Value = NumberFromString; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("string containing a number") - } - - fn visit_str(self, s: &str) -> Result - where - E: de::Error, - { - let n = tri!(s.parse().map_err(de::Error::custom)); - Ok(NumberFromString { value: n }) - } - } - - deserializer.deserialize_str(Visitor) - } -} - -#[cfg(feature = "arbitrary_precision")] -fn invalid_number() -> Error { - Error::syntax(ErrorCode::InvalidNumber, 0, 0) -} - -macro_rules! deserialize_any { - (@expand [$($num_string:tt)*]) => { - #[cfg(not(feature = "arbitrary_precision"))] - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self.n { - N::PosInt(u) => visitor.visit_u64(u), - N::NegInt(i) => visitor.visit_i64(i), - N::Float(f) => visitor.visit_f64(f), - } - } - - #[cfg(feature = "arbitrary_precision")] - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where V: Visitor<'de> - { - if let Some(u) = self.as_u64() { - return visitor.visit_u64(u); - } else if let Some(i) = self.as_i64() { - return visitor.visit_i64(i); - } else if let Some(f) = self.as_f64() { - if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n { - return visitor.visit_f64(f); - } - } - - visitor.visit_map(NumberDeserializer { - number: Some(self.$($num_string)*), - }) - } - }; - - (owned) => { - deserialize_any!(@expand [n]); - }; - - (ref) => { - deserialize_any!(@expand [n.clone()]); - }; -} - -macro_rules! deserialize_number { - ($deserialize:ident => $visit:ident) => { - #[cfg(not(feature = "arbitrary_precision"))] - fn $deserialize(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_any(visitor) - } - - #[cfg(feature = "arbitrary_precision")] - fn $deserialize(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.$visit(self.n.parse().map_err(|_| invalid_number())?) - } - }; -} - -impl<'de> Deserializer<'de> for Number { - type Error = Error; - - deserialize_any!(owned); - - deserialize_number!(deserialize_i8 => visit_i8); - deserialize_number!(deserialize_i16 => visit_i16); - deserialize_number!(deserialize_i32 => visit_i32); - deserialize_number!(deserialize_i64 => visit_i64); - 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_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 - ignored_any - } -} - -impl<'de, 'a> Deserializer<'de> for &'a Number { - type Error = Error; - - deserialize_any!(ref); - - deserialize_number!(deserialize_i8 => visit_i8); - deserialize_number!(deserialize_i16 => visit_i16); - deserialize_number!(deserialize_i32 => visit_i32); - deserialize_number!(deserialize_i64 => visit_i64); - 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_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 - ignored_any - } -} - -#[cfg(feature = "arbitrary_precision")] -pub(crate) struct NumberDeserializer { - pub number: Option, -} - -#[cfg(feature = "arbitrary_precision")] -impl<'de> MapAccess<'de> for NumberDeserializer { - type Error = Error; - - fn next_key_seed(&mut self, seed: K) -> Result, Error> - where - K: de::DeserializeSeed<'de>, - { - if self.number.is_none() { - return Ok(None); - } - seed.deserialize(NumberFieldDeserializer).map(Some) - } - - fn next_value_seed(&mut self, seed: V) -> Result - where - V: de::DeserializeSeed<'de>, - { - seed.deserialize(self.number.take().unwrap().into_deserializer()) - } -} - -#[cfg(feature = "arbitrary_precision")] -struct NumberFieldDeserializer; - -#[cfg(feature = "arbitrary_precision")] -impl<'de> Deserializer<'de> for NumberFieldDeserializer { - type Error = Error; - - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_borrowed_str(TOKEN) - } - - forward_to_deserialize_any! { - bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq - bytes byte_buf map struct option unit newtype_struct ignored_any - unit_struct tuple_struct tuple enum identifier - } -} - -impl From for Number { - fn from(value: ParserNumber) -> Self { - let n = match value { - ParserNumber::F64(f) => { - #[cfg(not(feature = "arbitrary_precision"))] - { - N::Float(f) - } - #[cfg(feature = "arbitrary_precision")] - { - f.to_string() - } - } - ParserNumber::U64(u) => { - #[cfg(not(feature = "arbitrary_precision"))] - { - N::PosInt(u) - } - #[cfg(feature = "arbitrary_precision")] - { - u.to_string() - } - } - ParserNumber::I64(i) => { - #[cfg(not(feature = "arbitrary_precision"))] - { - N::NegInt(i) - } - #[cfg(feature = "arbitrary_precision")] - { - i.to_string() - } - } - #[cfg(feature = "arbitrary_precision")] - ParserNumber::String(s) => s, - }; - Number { n: n } - } -} - -macro_rules! impl_from_unsigned { - ( - $($ty:ty),* - ) => { - $( - impl From<$ty> for Number { - #[inline] - fn from(u: $ty) -> Self { - let n = { - #[cfg(not(feature = "arbitrary_precision"))] - { N::PosInt(u as u64) } - #[cfg(feature = "arbitrary_precision")] - { - itoa::Buffer::new().format(u).to_owned() - } - }; - Number { n: n } - } - } - )* - }; -} - -macro_rules! impl_from_signed { - ( - $($ty:ty),* - ) => { - $( - impl From<$ty> for Number { - #[inline] - fn from(i: $ty) -> Self { - let n = { - #[cfg(not(feature = "arbitrary_precision"))] - { - if i < 0 { - N::NegInt(i as i64) - } else { - N::PosInt(i as u64) - } - } - #[cfg(feature = "arbitrary_precision")] - { - itoa::Buffer::new().format(i).to_owned() - } - }; - Number { n: n } - } - } - )* - }; -} - -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 for Number { - fn from(i: i128) -> Self { - Number { n: i.to_string() } - } - } - - impl From for Number { - fn from(u: u128) -> Self { - Number { n: u.to_string() } - } - } -} - -impl Number { - #[cfg(not(feature = "arbitrary_precision"))] - #[cold] - pub(crate) fn unexpected(&self) -> Unexpected { - match self.n { - N::PosInt(u) => Unexpected::Unsigned(u), - N::NegInt(i) => Unexpected::Signed(i), - N::Float(f) => Unexpected::Float(f), - } - } - - #[cfg(feature = "arbitrary_precision")] - #[cold] - pub(crate) fn unexpected(&self) -> Unexpected { - Unexpected::Other("number") - } -} diff --git a/json/src/raw.rs b/json/src/raw.rs deleted file mode 100644 index c373b4de..00000000 --- a/json/src/raw.rs +++ /dev/null @@ -1,514 +0,0 @@ -use crate::error::Error; -use crate::lib::*; -use serde::de::value::BorrowedStrDeserializer; -use serde::de::{ - self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected, - Visitor, -}; -use serde::forward_to_deserialize_any; -use serde::ser::{Serialize, SerializeStruct, Serializer}; - -/// Reference to a range of bytes encompassing a single valid JSON value in the -/// input data. -/// -/// A `RawValue` can be used to defer parsing parts of a payload until later, -/// or to avoid parsing it at all in the case that part of the payload just -/// needs to be transferred verbatim into a different output object. -/// -/// When serializing, a value of this type will retain its original formatting -/// and will not be minified or pretty-printed. -/// -/// # Note -/// -/// `RawValue` is only available if serde\_json is built with the `"raw_value"` -/// feature. -/// -/// ```toml -/// [dependencies] -/// serde_json = { version = "1.0", features = ["raw_value"] } -/// ``` -/// -/// # Example -/// -/// ``` -/// use serde::{Deserialize, Serialize}; -/// use serde_json::{Result, value::RawValue}; -/// -/// #[derive(Deserialize)] -/// struct Input<'a> { -/// code: u32, -/// #[serde(borrow)] -/// payload: &'a RawValue, -/// } -/// -/// #[derive(Serialize)] -/// struct Output<'a> { -/// info: (u32, &'a RawValue), -/// } -/// -/// // Efficiently rearrange JSON input containing separate "code" and "payload" -/// // keys into a single "info" key holding an array of code and payload. -/// // -/// // This could be done equivalently using serde_json::Value as the type for -/// // payload, but &RawValue will perform better because it does not require -/// // memory allocation. The correct range of bytes is borrowed from the input -/// // data and pasted verbatim into the output. -/// fn rearrange(input: &str) -> Result { -/// let input: Input = serde_json::from_str(input)?; -/// -/// let output = Output { -/// info: (input.code, input.payload), -/// }; -/// -/// serde_json::to_string(&output) -/// } -/// -/// fn main() -> Result<()> { -/// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?; -/// -/// assert_eq!(out, r#"{"info":[200,{}]}"#); -/// -/// Ok(()) -/// } -/// ``` -/// -/// # Ownership -/// -/// The typical usage of `RawValue` will be in the borrowed form: -/// -/// ``` -/// # use serde::Deserialize; -/// # use serde_json::value::RawValue; -/// # -/// #[derive(Deserialize)] -/// struct SomeStruct<'a> { -/// #[serde(borrow)] -/// raw_value: &'a RawValue, -/// } -/// ``` -/// -/// The borrowed form is suitable when deserializing through -/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support -/// borrowing from the input data without memory allocation. -/// -/// When deserializing through [`serde_json::from_reader`] you will need to use -/// the boxed form of `RawValue` instead. This is almost as efficient but -/// involves buffering the raw value from the I/O stream into memory. -/// -/// [`serde_json::from_str`]: ../fn.from_str.html -/// [`serde_json::from_slice`]: ../fn.from_slice.html -/// [`serde_json::from_reader`]: ../fn.from_reader.html -/// -/// ``` -/// # use serde::Deserialize; -/// # use serde_json::value::RawValue; -/// # -/// #[derive(Deserialize)] -/// struct SomeStruct { -/// raw_value: Box, -/// } -/// ``` -#[repr(C)] -pub struct RawValue { - json: str, -} - -impl RawValue { - fn from_borrowed(json: &str) -> &Self { - unsafe { mem::transmute::<&str, &RawValue>(json) } - } - - fn from_owned(json: Box) -> Box { - unsafe { mem::transmute::, Box>(json) } - } -} - -impl Clone for Box { - fn clone(&self) -> Self { - (**self).to_owned() - } -} - -impl ToOwned for RawValue { - type Owned = Box; - - fn to_owned(&self) -> Self::Owned { - RawValue::from_owned(self.json.to_owned().into_boxed_str()) - } -} - -impl Default for Box { - fn default() -> Self { - RawValue::from_borrowed("null").to_owned() - } -} - -impl Debug for RawValue { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter - .debug_tuple("RawValue") - .field(&format_args!("{}", &self.json)) - .finish() - } -} - -impl Display for RawValue { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&self.json) - } -} - -impl RawValue { - /// Convert an owned `String` of JSON data to an owned `RawValue`. - /// - /// This function is equivalent to `serde_json::from_str::>` - /// except that we avoid an allocation and memcpy if both of the following - /// are true: - /// - /// - the input has no leading or trailing whitespace, and - /// - the input has capacity equal to its length. - pub fn from_string(json: String) -> Result, Error> { - { - let borrowed = crate::from_str::<&Self>(&json)?; - if borrowed.json.len() < json.len() { - return Ok(borrowed.to_owned()); - } - } - Ok(Self::from_owned(json.into_boxed_str())) - } - - /// Access the JSON text underlying a raw value. - /// - /// # Example - /// - /// ``` - /// use serde::Deserialize; - /// use serde_json::{Result, value::RawValue}; - /// - /// #[derive(Deserialize)] - /// struct Response<'a> { - /// code: u32, - /// #[serde(borrow)] - /// payload: &'a RawValue, - /// } - /// - /// fn process(input: &str) -> Result<()> { - /// let response: Response = serde_json::from_str(input)?; - /// - /// let payload = response.payload.get(); - /// if payload.starts_with('{') { - /// // handle a payload which is a JSON map - /// } else { - /// // handle any other type - /// } - /// - /// Ok(()) - /// } - /// - /// fn main() -> Result<()> { - /// process(r#" {"code": 200, "payload": {}} "#)?; - /// Ok(()) - /// } - /// ``` - pub fn get(&self) -> &str { - &self.json - } -} - -/// Convert a `T` into a boxed `RawValue`. -/// -/// # Example -/// -/// ``` -/// // Upstream crate -/// # #[derive(Serialize)] -/// pub struct Thing { -/// foo: String, -/// bar: Option, -/// extra_data: Box, -/// } -/// -/// // Local crate -/// use serde::Serialize; -/// use serde_json::value::{to_raw_value, RawValue}; -/// -/// #[derive(Serialize)] -/// struct MyExtraData { -/// a: u32, -/// b: u32, -/// } -/// -/// let my_thing = Thing { -/// foo: "FooVal".into(), -/// bar: None, -/// extra_data: to_raw_value(&MyExtraData { a: 1, b: 2 }).unwrap(), -/// }; -/// # assert_eq!( -/// # serde_json::to_value(my_thing).unwrap(), -/// # serde_json::json!({ -/// # "foo": "FooVal", -/// # "bar": null, -/// # "extra_data": { "a": 1, "b": 2 } -/// # }) -/// # ); -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -/// -/// ``` -/// use std::collections::BTreeMap; -/// -/// // The keys in this map are vectors, not strings. -/// let mut map = BTreeMap::new(); -/// map.insert(vec![32, 64], "x86"); -/// -/// println!("{}", serde_json::value::to_raw_value(&map).unwrap_err()); -/// ``` -pub fn to_raw_value(value: &T) -> Result, Error> -where - T: Serialize, -{ - let json_string = crate::to_string(value)?; - Ok(RawValue::from_owned(json_string.into_boxed_str())) -} - -pub const TOKEN: &str = "$serde_json::private::RawValue"; - -impl Serialize for RawValue { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let mut s = serializer.serialize_struct(TOKEN, 1)?; - s.serialize_field(TOKEN, &self.json)?; - s.end() - } -} - -impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct ReferenceVisitor; - - impl<'de> Visitor<'de> for ReferenceVisitor { - type Value = &'de RawValue; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "any valid JSON value") - } - - fn visit_map(self, mut visitor: V) -> Result - where - V: MapAccess<'de>, - { - let value = visitor.next_key::()?; - if value.is_none() { - return Err(de::Error::invalid_type(Unexpected::Map, &self)); - } - visitor.next_value_seed(ReferenceFromString) - } - } - - deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor) - } -} - -impl<'de> Deserialize<'de> for Box { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct BoxedVisitor; - - impl<'de> Visitor<'de> for BoxedVisitor { - type Value = Box; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - write!(formatter, "any valid JSON value") - } - - fn visit_map(self, mut visitor: V) -> Result - where - V: MapAccess<'de>, - { - let value = visitor.next_key::()?; - if value.is_none() { - return Err(de::Error::invalid_type(Unexpected::Map, &self)); - } - visitor.next_value_seed(BoxedFromString) - } - } - - deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor) - } -} - -struct RawKey; - -impl<'de> Deserialize<'de> for RawKey { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct FieldVisitor; - - impl<'de> Visitor<'de> for FieldVisitor { - type Value = (); - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("raw value") - } - - fn visit_str(self, s: &str) -> Result<(), E> - where - E: de::Error, - { - if s == TOKEN { - Ok(()) - } else { - Err(de::Error::custom("unexpected raw value")) - } - } - } - - deserializer.deserialize_identifier(FieldVisitor)?; - Ok(RawKey) - } -} - -pub struct ReferenceFromString; - -impl<'de> DeserializeSeed<'de> for ReferenceFromString { - type Value = &'de RawValue; - - fn deserialize(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_str(self) - } -} - -impl<'de> Visitor<'de> for ReferenceFromString { - type Value = &'de RawValue; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("raw value") - } - - fn visit_borrowed_str(self, s: &'de str) -> Result - where - E: de::Error, - { - Ok(RawValue::from_borrowed(s)) - } -} - -pub struct BoxedFromString; - -impl<'de> DeserializeSeed<'de> for BoxedFromString { - type Value = Box; - - fn deserialize(self, deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_str(self) - } -} - -impl<'de> Visitor<'de> for BoxedFromString { - type Value = Box; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("raw value") - } - - fn visit_str(self, s: &str) -> Result - where - E: de::Error, - { - self.visit_string(s.to_owned()) - } - - fn visit_string(self, s: String) -> Result - where - E: de::Error, - { - Ok(RawValue::from_owned(s.into_boxed_str())) - } -} - -struct RawKeyDeserializer; - -impl<'de> Deserializer<'de> for RawKeyDeserializer { - type Error = Error; - - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_borrowed_str(TOKEN) - } - - forward_to_deserialize_any! { - bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq - bytes byte_buf map struct option unit newtype_struct ignored_any - unit_struct tuple_struct tuple enum identifier - } -} - -pub struct OwnedRawDeserializer { - pub raw_value: Option, -} - -impl<'de> MapAccess<'de> for OwnedRawDeserializer { - type Error = Error; - - fn next_key_seed(&mut self, seed: K) -> Result, Error> - where - K: de::DeserializeSeed<'de>, - { - if self.raw_value.is_none() { - return Ok(None); - } - seed.deserialize(RawKeyDeserializer).map(Some) - } - - fn next_value_seed(&mut self, seed: V) -> Result - where - V: de::DeserializeSeed<'de>, - { - seed.deserialize(self.raw_value.take().unwrap().into_deserializer()) - } -} - -pub struct BorrowedRawDeserializer<'de> { - pub raw_value: Option<&'de str>, -} - -impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> { - type Error = Error; - - fn next_key_seed(&mut self, seed: K) -> Result, Error> - where - K: de::DeserializeSeed<'de>, - { - if self.raw_value.is_none() { - return Ok(None); - } - seed.deserialize(RawKeyDeserializer).map(Some) - } - - fn next_value_seed(&mut self, seed: V) -> Result - where - V: de::DeserializeSeed<'de>, - { - seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap())) - } -} diff --git a/json/src/read.rs b/json/src/read.rs deleted file mode 100644 index 64631ecf..00000000 --- a/json/src/read.rs +++ /dev/null @@ -1,942 +0,0 @@ -use crate::error::{Error, ErrorCode, Result}; -use crate::lib::ops::Deref; -use crate::lib::*; - -#[cfg(feature = "std")] -use crate::io; -#[cfg(feature = "std")] -use crate::iter::LineColIterator; - -#[cfg(feature = "raw_value")] -use crate::raw::BorrowedRawDeserializer; -#[cfg(all(feature = "raw_value", feature = "std"))] -use crate::raw::OwnedRawDeserializer; -#[cfg(feature = "raw_value")] -use serde::de::Visitor; - -/// Trait used by the deserializer for iterating over input. This is manually -/// "specialized" for iterating over &[u8]. Once feature(specialization) is -/// stable we can use actual specialization. -/// -/// This trait is sealed and cannot be implemented for types outside of -/// `serde_json`. -pub trait Read<'de>: private::Sealed { - #[doc(hidden)] - fn next(&mut self) -> Result>; - #[doc(hidden)] - fn peek(&mut self) -> Result>; - - /// Only valid after a call to peek(). Discards the peeked byte. - #[doc(hidden)] - fn discard(&mut self); - - /// Position of the most recent call to next(). - /// - /// The most recent call was probably next() and not peek(), but this method - /// should try to return a sensible result if the most recent call was - /// actually peek() because we don't always know. - /// - /// Only called in case of an error, so performance is not important. - #[doc(hidden)] - fn position(&self) -> Position; - - /// Position of the most recent call to peek(). - /// - /// The most recent call was probably peek() and not next(), but this method - /// should try to return a sensible result if the most recent call was - /// actually next() because we don't always know. - /// - /// Only called in case of an error, so performance is not important. - #[doc(hidden)] - fn peek_position(&self) -> Position; - - /// Offset from the beginning of the input to the next byte that would be - /// returned by next() or peek(). - #[doc(hidden)] - fn byte_offset(&self) -> usize; - - #[doc(hidden)] - fn slice_looking_back(&self, start: usize) -> Option<&[u8]>; - - /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped - /// string until the next quotation mark using the given scratch space if - /// necessary. The scratch space is initially empty. - #[doc(hidden)] - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; - - /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped - /// string until the next quotation mark using the given scratch space if - /// necessary. The scratch space is initially empty. - /// - /// This function returns the raw bytes in the string with escape sequences - /// expanded but without performing unicode validation. - #[doc(hidden)] - fn parse_str_raw<'s>( - &'s mut self, - scratch: &'s mut Vec, - ) -> Result>; - - /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped - /// string until the next quotation mark but discards the data. - #[doc(hidden)] - fn ignore_str(&mut self) -> Result<()>; - - /// Assumes the previous byte was a hex escape sequnce ('\u') in a string. - /// Parses next hexadecimal sequence. - #[doc(hidden)] - fn decode_hex_escape(&mut self) -> Result; - - /// Switch raw buffering mode on. - /// - /// This is used when deserializing `RawValue`. - #[cfg(feature = "raw_value")] - #[doc(hidden)] - fn begin_raw_buffering(&mut self); - - /// Switch raw buffering mode off and provides the raw buffered data to the - /// given visitor. - #[cfg(feature = "raw_value")] - #[doc(hidden)] - fn end_raw_buffering(&mut self, visitor: V) -> Result - where - V: Visitor<'de>; - - /// Whether StreamDeserializer::next needs to check the failed flag. True - /// for IoRead, false for StrRead and SliceRead which can track failure by - /// truncating their input slice to avoid the extra check on every next - /// call. - #[doc(hidden)] - const should_early_return_if_failed: bool; - - /// Mark a persistent failure of StreamDeserializer, either by setting the - /// flag or by truncating the input data. - #[doc(hidden)] - fn set_failed(&mut self, failed: &mut bool); -} - -pub struct Position { - pub line: usize, - pub column: usize, -} - -pub enum Reference<'b, 'c, T> -where - T: ?Sized + 'static, -{ - Borrowed(&'b T), - Copied(&'c T), -} - -impl<'b, 'c, T> Deref for Reference<'b, 'c, T> -where - T: ?Sized + 'static, -{ - type Target = T; - - fn deref(&self) -> &Self::Target { - match *self { - Reference::Borrowed(b) => b, - Reference::Copied(c) => c, - } - } -} - -/// JSON input source that reads from a std::io input stream. -#[cfg(feature = "std")] -pub struct IoRead -where - R: io::Read, -{ - iter: LineColIterator>, - /// Temporary storage of peeked byte. - ch: Option, - #[cfg(feature = "raw_value")] - raw_buffer: Option>, -} - -/// JSON input source that reads from a slice of bytes. -// -// This is more efficient than other iterators because peek() can be read-only -// and we can compute line/col position only if an error happens. -pub struct SliceRead<'a> { - slice: &'a [u8], - /// Index of the *next* byte that will be returned by next() or peek(). - index: usize, - #[cfg(feature = "raw_value")] - raw_buffering_start_index: usize, -} - -/// JSON input source that reads from a UTF-8 string. -// -// Able to elide UTF-8 checks by assuming that the input is valid UTF-8. -pub struct StrRead<'a> { - delegate: SliceRead<'a>, - #[cfg(feature = "raw_value")] - data: &'a str, -} - -// Prevent users from implementing the Read trait. -mod private { - pub trait Sealed {} -} - -////////////////////////////////////////////////////////////////////////////// - -#[cfg(feature = "std")] -impl IoRead -where - R: io::Read, -{ - /// Create a JSON input source to read from a std::io input stream. - pub fn new(reader: R) -> Self { - #[cfg(not(feature = "raw_value"))] - { - IoRead { - iter: LineColIterator::new(reader.bytes()), - ch: None, - } - } - #[cfg(feature = "raw_value")] - { - IoRead { - iter: LineColIterator::new(reader.bytes()), - ch: None, - raw_buffer: None, - } - } - } -} - -#[cfg(feature = "std")] -impl private::Sealed for IoRead where R: io::Read {} - -#[cfg(feature = "std")] -impl IoRead -where - R: io::Read, -{ - fn parse_str_bytes<'s, T, F>( - &'s mut self, - scratch: &'s mut Vec, - validate: bool, - result: F, - ) -> Result - where - T: 's, - F: FnOnce(&'s Self, &'s [u8]) -> Result, - { - loop { - let ch = tri!(next_or_eof(self)); - if !ESCAPE[ch as usize] { - scratch.push(ch); - continue; - } - match ch { - b'"' => { - return result(self, scratch); - } - b'\\' => { - tri!(parse_escape(self, scratch)); - } - _ => { - if validate { - return error(self, ErrorCode::ControlCharacterWhileParsingString); - } - scratch.push(ch); - } - } - } - } -} - -#[cfg(feature = "std")] -impl<'de, R> Read<'de> for IoRead -where - R: io::Read, -{ - #[inline] - fn next(&mut self) -> Result> { - match self.ch.take() { - Some(ch) => { - #[cfg(feature = "raw_value")] - { - if let Some(ref mut buf) = self.raw_buffer { - buf.push(ch); - } - } - Ok(Some(ch)) - } - None => match self.iter.next() { - Some(Err(err)) => Err(Error::io(err)), - Some(Ok(ch)) => { - #[cfg(feature = "raw_value")] - { - if let Some(ref mut buf) = self.raw_buffer { - buf.push(ch); - } - } - Ok(Some(ch)) - } - None => Ok(None), - }, - } - } - - #[inline] - fn peek(&mut self) -> Result> { - match self.ch { - Some(ch) => Ok(Some(ch)), - None => match self.iter.next() { - Some(Err(err)) => Err(Error::io(err)), - Some(Ok(ch)) => { - self.ch = Some(ch); - Ok(self.ch) - } - None => Ok(None), - }, - } - } - - #[cfg(not(feature = "raw_value"))] - #[inline] - fn discard(&mut self) { - self.ch = None; - } - - #[cfg(feature = "raw_value")] - fn discard(&mut self) { - if let Some(ch) = self.ch.take() { - if let Some(ref mut buf) = self.raw_buffer { - buf.push(ch); - } - } - } - - fn position(&self) -> Position { - Position { - line: self.iter.line(), - column: self.iter.col(), - } - } - - fn peek_position(&self) -> Position { - // The LineColIterator updates its position during peek() so it has the - // right one here. - self.position() - } - - fn byte_offset(&self) -> usize { - match self.ch { - Some(_) => self.iter.byte_offset() - 1, - None => self.iter.byte_offset(), - } - } - - fn slice_looking_back(&self, _start: usize) -> Option<&[u8]> { - unimplemented!() - } - - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.parse_str_bytes(scratch, true, as_str) - .map(Reference::Copied) - } - - fn parse_str_raw<'s>( - &'s mut self, - scratch: &'s mut Vec, - ) -> Result> { - self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) - .map(Reference::Copied) - } - - fn ignore_str(&mut self) -> Result<()> { - loop { - let ch = tri!(next_or_eof(self)); - if !ESCAPE[ch as usize] { - continue; - } - match ch { - b'"' => { - return Ok(()); - } - b'\\' => { - tri!(ignore_escape(self)); - } - _ => { - return error(self, ErrorCode::ControlCharacterWhileParsingString); - } - } - } - } - - fn decode_hex_escape(&mut self) -> Result { - let mut n = 0; - for _ in 0..4 { - match decode_hex_val(tri!(next_or_eof(self))) { - None => return error(self, ErrorCode::InvalidEscape), - Some(val) => { - n = (n << 4) + val; - } - } - } - Ok(n) - } - - #[cfg(feature = "raw_value")] - fn begin_raw_buffering(&mut self) { - self.raw_buffer = Some(Vec::new()); - } - - #[cfg(feature = "raw_value")] - fn end_raw_buffering(&mut self, visitor: V) -> Result - where - V: Visitor<'de>, - { - let raw = self.raw_buffer.take().unwrap(); - let raw = String::from_utf8(raw).unwrap(); - visitor.visit_map(OwnedRawDeserializer { - raw_value: Some(raw), - }) - } - - const should_early_return_if_failed: bool = true; - - #[inline] - #[cold] - fn set_failed(&mut self, failed: &mut bool) { - *failed = true; - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl<'a> SliceRead<'a> { - /// Create a JSON input source to read from a slice of bytes. - pub fn new(slice: &'a [u8]) -> Self { - #[cfg(not(feature = "raw_value"))] - { - SliceRead { - slice: slice, - index: 0, - } - } - #[cfg(feature = "raw_value")] - { - SliceRead { - slice: slice, - index: 0, - raw_buffering_start_index: 0, - } - } - } - - fn position_of_index(&self, i: usize) -> Position { - let mut position = Position { line: 1, column: 0 }; - for ch in &self.slice[..i] { - match *ch { - b'\n' => { - position.line += 1; - position.column = 0; - } - _ => { - position.column += 1; - } - } - } - position - } - - /// The big optimization here over IoRead is that if the string contains no - /// backslash escape sequences, the returned &str is a slice of the raw JSON - /// data so we avoid copying into the scratch space. - fn parse_str_bytes<'s, T, F>( - &'s mut self, - scratch: &'s mut Vec, - validate: bool, - result: F, - ) -> Result> - where - T: ?Sized + 's, - F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, - { - // Index of the first byte not yet copied into the scratch space. - let mut start = self.index; - - loop { - while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { - self.index += 1; - } - if self.index == self.slice.len() { - return error(self, ErrorCode::EofWhileParsingString); - } - match self.slice[self.index] { - b'"' => { - if scratch.is_empty() { - // Fast path: return a slice of the raw JSON without any - // copying. - let borrowed = &self.slice[start..self.index]; - self.index += 1; - return result(self, borrowed).map(Reference::Borrowed); - } else { - scratch.extend_from_slice(&self.slice[start..self.index]); - self.index += 1; - return result(self, scratch).map(Reference::Copied); - } - } - b'\\' => { - scratch.extend_from_slice(&self.slice[start..self.index]); - self.index += 1; - tri!(parse_escape(self, scratch)); - start = self.index; - } - _ => { - self.index += 1; - if validate { - return error(self, ErrorCode::ControlCharacterWhileParsingString); - } - } - } - } - } -} - -impl<'a> private::Sealed for SliceRead<'a> {} - -impl<'a> Read<'a> for SliceRead<'a> { - #[inline] - fn next(&mut self) -> Result> { - // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` - // is about 10% slower. - Ok(if self.index < self.slice.len() { - let ch = self.slice[self.index]; - self.index += 1; - Some(ch) - } else { - None - }) - } - - #[inline] - fn peek(&mut self) -> Result> { - // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower - // for some reason. - Ok(if self.index < self.slice.len() { - Some(self.slice[self.index]) - } else { - None - }) - } - - #[inline] - fn discard(&mut self) { - self.index += 1; - } - - fn position(&self) -> Position { - self.position_of_index(self.index) - } - - fn peek_position(&self) -> Position { - // Cap it at slice.len() just in case the most recent call was next() - // and it returned the last byte. - self.position_of_index(cmp::min(self.slice.len(), self.index + 1)) - } - - fn byte_offset(&self) -> usize { - self.index - } - - fn slice_looking_back(&self, start: usize) -> Option<&[u8]> { - if self.byte_offset() > start { - Some(&self.slice[start..self.index]) - } else { - None - } - } - - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.parse_str_bytes(scratch, true, as_str) - } - - fn parse_str_raw<'s>( - &'s mut self, - scratch: &'s mut Vec, - ) -> Result> { - self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) - } - - fn ignore_str(&mut self) -> Result<()> { - loop { - while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { - self.index += 1; - } - if self.index == self.slice.len() { - return error(self, ErrorCode::EofWhileParsingString); - } - match self.slice[self.index] { - b'"' => { - self.index += 1; - return Ok(()); - } - b'\\' => { - self.index += 1; - tri!(ignore_escape(self)); - } - _ => { - return error(self, ErrorCode::ControlCharacterWhileParsingString); - } - } - } - } - - fn decode_hex_escape(&mut self) -> Result { - if self.index + 4 > self.slice.len() { - self.index = self.slice.len(); - return error(self, ErrorCode::EofWhileParsingString); - } - - let mut n = 0; - for _ in 0..4 { - let ch = decode_hex_val(self.slice[self.index]); - self.index += 1; - match ch { - None => return error(self, ErrorCode::InvalidEscape), - Some(val) => { - n = (n << 4) + val; - } - } - } - Ok(n) - } - - #[cfg(feature = "raw_value")] - fn begin_raw_buffering(&mut self) { - self.raw_buffering_start_index = self.index; - } - - #[cfg(feature = "raw_value")] - fn end_raw_buffering(&mut self, visitor: V) -> Result - where - V: Visitor<'a>, - { - let raw = &self.slice[self.raw_buffering_start_index..self.index]; - let raw = str::from_utf8(raw).unwrap(); - visitor.visit_map(BorrowedRawDeserializer { - raw_value: Some(raw), - }) - } - - const should_early_return_if_failed: bool = false; - - #[inline] - #[cold] - fn set_failed(&mut self, _failed: &mut bool) { - self.slice = &self.slice[..self.index]; - } -} - -////////////////////////////////////////////////////////////////////////////// - -impl<'a> StrRead<'a> { - /// Create a JSON input source to read from a UTF-8 string. - pub fn new(s: &'a str) -> Self { - #[cfg(not(feature = "raw_value"))] - { - StrRead { - delegate: SliceRead::new(s.as_bytes()), - } - } - #[cfg(feature = "raw_value")] - { - StrRead { - delegate: SliceRead::new(s.as_bytes()), - data: s, - } - } - } -} - -impl<'a> private::Sealed for StrRead<'a> {} - -impl<'a> Read<'a> for StrRead<'a> { - #[inline] - fn next(&mut self) -> Result> { - self.delegate.next() - } - - #[inline] - fn peek(&mut self) -> Result> { - self.delegate.peek() - } - - #[inline] - fn discard(&mut self) { - self.delegate.discard(); - } - - fn position(&self) -> Position { - self.delegate.position() - } - - fn peek_position(&self) -> Position { - self.delegate.peek_position() - } - - fn byte_offset(&self) -> usize { - self.delegate.byte_offset() - } - - fn slice_looking_back(&self, start: usize) -> Option<&[u8]> { - self.delegate.slice_looking_back(start) - } - - fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { - self.delegate.parse_str_bytes(scratch, true, |_, bytes| { - // The input is assumed to be valid UTF-8 and the \u-escapes are - // checked along the way, so don't need to check here. - Ok(unsafe { str::from_utf8_unchecked(bytes) }) - }) - } - - fn parse_str_raw<'s>( - &'s mut self, - scratch: &'s mut Vec, - ) -> Result> { - self.delegate.parse_str_raw(scratch) - } - - fn ignore_str(&mut self) -> Result<()> { - self.delegate.ignore_str() - } - - fn decode_hex_escape(&mut self) -> Result { - self.delegate.decode_hex_escape() - } - - #[cfg(feature = "raw_value")] - fn begin_raw_buffering(&mut self) { - self.delegate.begin_raw_buffering() - } - - #[cfg(feature = "raw_value")] - fn end_raw_buffering(&mut self, visitor: V) -> Result - where - V: Visitor<'a>, - { - let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index]; - visitor.visit_map(BorrowedRawDeserializer { - raw_value: Some(raw), - }) - } - - const should_early_return_if_failed: bool = false; - - #[inline] - #[cold] - fn set_failed(&mut self, failed: &mut bool) { - self.delegate.set_failed(failed); - } -} - -////////////////////////////////////////////////////////////////////////////// - -/// Marker for whether StreamDeserializer can implement FusedIterator. -pub trait Fused: private::Sealed {} -impl<'a> Fused for SliceRead<'a> {} -impl<'a> Fused for StrRead<'a> {} - -// Lookup table of bytes that must be escaped. A value of true at index i means -// that byte i requires an escape sequence in the input. -static ESCAPE: [bool; 256] = { - const CT: bool = true; // control character \x00..=\x1F - const QU: bool = true; // quote \x22 - const BS: bool = true; // backslash \x5C - const __: bool = false; // allow unescaped - [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 - CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 - __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 - __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F - ] -}; - -fn next_or_eof<'de, R>(read: &mut R) -> Result -where - R: ?Sized + Read<'de>, -{ - match tri!(read.next()) { - Some(b) => Ok(b), - None => error(read, ErrorCode::EofWhileParsingString), - } -} - -fn error<'de, R, T>(read: &R, reason: ErrorCode) -> Result -where - R: ?Sized + Read<'de>, -{ - let position = read.position(); - Err(Error::syntax(reason, position.line, position.column)) -} - -fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> { - str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint)) -} - -/// Parses a JSON escape sequence and appends it into the scratch space. Assumes -/// the previous byte read was a backslash. -fn parse_escape<'de, R: Read<'de>>(read: &mut R, scratch: &mut Vec) -> Result<()> { - let ch = tri!(next_or_eof(read)); - - match ch { - b'"' => scratch.push(b'"'), - b'\\' => scratch.push(b'\\'), - b'/' => scratch.push(b'/'), - b'b' => scratch.push(b'\x08'), - b'f' => scratch.push(b'\x0c'), - b'n' => scratch.push(b'\n'), - b'r' => scratch.push(b'\r'), - b't' => scratch.push(b'\t'), - b'u' => { - let c = match tri!(read.decode_hex_escape()) { - 0xDC00..=0xDFFF => { - return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); - } - - // Non-BMP characters are encoded as a sequence of - // two hex escapes, representing UTF-16 surrogates. - n1 @ 0xD800..=0xDBFF => { - if tri!(next_or_eof(read)) != b'\\' { - return error(read, ErrorCode::UnexpectedEndOfHexEscape); - } - if tri!(next_or_eof(read)) != b'u' { - return error(read, ErrorCode::UnexpectedEndOfHexEscape); - } - - let n2 = tri!(read.decode_hex_escape()); - - if n2 < 0xDC00 || n2 > 0xDFFF { - return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); - } - - let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; - - match char::from_u32(n) { - Some(c) => c, - None => { - return error(read, ErrorCode::InvalidUnicodeCodePoint); - } - } - } - - n => match char::from_u32(n as u32) { - Some(c) => c, - None => { - return error(read, ErrorCode::InvalidUnicodeCodePoint); - } - }, - }; - - scratch.extend_from_slice(c.encode_utf8(&mut [0_u8; 4]).as_bytes()); - } - _ => { - return error(read, ErrorCode::InvalidEscape); - } - } - - Ok(()) -} - -/// Parses a JSON escape sequence and discards the value. Assumes the previous -/// byte read was a backslash. -fn ignore_escape<'de, R>(read: &mut R) -> Result<()> -where - R: ?Sized + Read<'de>, -{ - let ch = tri!(next_or_eof(read)); - - match ch { - b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {} - b'u' => { - let n = match tri!(read.decode_hex_escape()) { - 0xDC00..=0xDFFF => { - return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); - } - - // Non-BMP characters are encoded as a sequence of - // two hex escapes, representing UTF-16 surrogates. - n1 @ 0xD800..=0xDBFF => { - if tri!(next_or_eof(read)) != b'\\' { - return error(read, ErrorCode::UnexpectedEndOfHexEscape); - } - if tri!(next_or_eof(read)) != b'u' { - return error(read, ErrorCode::UnexpectedEndOfHexEscape); - } - - let n2 = tri!(read.decode_hex_escape()); - - if n2 < 0xDC00 || n2 > 0xDFFF { - return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); - } - - (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000 - } - - n => n as u32, - }; - - if char::from_u32(n).is_none() { - return error(read, ErrorCode::InvalidUnicodeCodePoint); - } - } - _ => { - return error(read, ErrorCode::InvalidEscape); - } - } - - Ok(()) -} - -static HEX: [u8; 256] = { - const __: u8 = 255; // not a hex digit - [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 1 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 - 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, __, __, __, __, __, __, // 3 - __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 4 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 5 - __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 6 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F - ] -}; - -fn decode_hex_val(val: u8) -> Option { - let n = HEX[val as usize] as u16; - if n == 255 { - None - } else { - Some(n) - } -} diff --git a/json/src/ser.rs b/json/src/ser.rs deleted file mode 100644 index e62bc199..00000000 --- a/json/src/ser.rs +++ /dev/null @@ -1,2262 +0,0 @@ -//! Serialize a Rust data structure into JSON data. - -use crate::error::{Error, ErrorCode, Result}; -use crate::io; -use crate::lib::num::FpCategory; -use crate::lib::*; -use serde::ser::{self, Impossible, Serialize}; -use serde::serde_if_integer128; - -/// A structure for serializing Rust values into JSON. -pub struct Serializer { - writer: W, - formatter: F, -} - -impl Serializer -where - W: io::Write, -{ - /// Creates a new JSON serializer. - #[inline] - pub fn new(writer: W) -> Self { - Serializer::with_formatter(writer, CompactFormatter) - } -} - -impl<'a, W> Serializer> -where - W: io::Write, -{ - /// Creates a new JSON pretty print serializer. - #[inline] - pub fn pretty(writer: W) -> Self { - Serializer::with_formatter(writer, PrettyFormatter::new()) - } -} - -impl Serializer -where - W: io::Write, - F: Formatter, -{ - /// Creates a new JSON visitor whose output will be written to the writer - /// specified. - #[inline] - pub fn with_formatter(writer: W, formatter: F) -> Self { - Serializer { - writer: writer, - formatter: formatter, - } - } - - /// Unwrap the `Writer` from the `Serializer`. - #[inline] - pub fn into_inner(self) -> W { - self.writer - } -} - -impl<'a, W, F> ser::Serializer for &'a mut Serializer -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - type SerializeSeq = Compound<'a, W, F>; - type SerializeTuple = Compound<'a, W, F>; - type SerializeTupleStruct = Compound<'a, W, F>; - type SerializeTupleVariant = Compound<'a, W, F>; - type SerializeMap = Compound<'a, W, F>; - type SerializeStruct = Compound<'a, W, F>; - type SerializeStructVariant = Compound<'a, W, F>; - - #[inline] - fn serialize_bool(self, value: bool) -> Result<()> { - tri!(self - .formatter - .write_bool(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_i8(self, value: i8) -> Result<()> { - tri!(self - .formatter - .write_i8(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_i16(self, value: i16) -> Result<()> { - tri!(self - .formatter - .write_i16(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_i32(self, value: i32) -> Result<()> { - tri!(self - .formatter - .write_i32(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_i64(self, value: i64) -> Result<()> { - tri!(self - .formatter - .write_i64(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - 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) - } - } - - #[inline] - fn serialize_u8(self, value: u8) -> Result<()> { - tri!(self - .formatter - .write_u8(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_u16(self, value: u16) -> Result<()> { - tri!(self - .formatter - .write_u16(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_u32(self, value: u32) -> Result<()> { - tri!(self - .formatter - .write_u32(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_u64(self, value: u64) -> Result<()> { - tri!(self - .formatter - .write_u64(&mut self.writer, value) - .map_err(Error::io)); - Ok(()) - } - - 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) - } - } - - #[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)); - } - } - 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)); - } - } - Ok(()) - } - - #[inline] - fn serialize_char(self, value: char) -> Result<()> { - // A char encoded as UTF-8 takes 4 bytes at most. - let mut buf = [0; 4]; - self.serialize_str(value.encode_utf8(&mut buf)) - } - - #[inline] - fn serialize_str(self, value: &str) -> Result<()> { - tri!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_bytes(self, value: &[u8]) -> Result<()> { - use serde::ser::SerializeSeq; - let mut seq = tri!(self.serialize_seq(Some(value.len()))); - for byte in value { - tri!(seq.serialize_element(byte)); - } - seq.end() - } - - #[inline] - fn serialize_unit(self) -> Result<()> { - tri!(self - .formatter - .write_null(&mut self.writer) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { - self.serialize_unit() - } - - #[inline] - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - ) -> Result<()> { - self.serialize_str(variant) - } - - /// Serialize newtypes without an object wrapper. - #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - #[inline] - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - value: &T, - ) -> Result<()> - where - T: ?Sized + Serialize, - { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); - tri!(value.serialize(&mut *self)); - tri!(self - .formatter - .end_object_value(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .end_object(&mut self.writer) - .map_err(Error::io)); - Ok(()) - } - - #[inline] - fn serialize_none(self) -> Result<()> { - self.serialize_unit() - } - - #[inline] - fn serialize_some(self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - #[inline] - fn serialize_seq(self, len: Option) -> Result { - if len == Some(0) { - tri!(self - .formatter - .begin_array(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .end_array(&mut self.writer) - .map_err(Error::io)); - Ok(Compound::Map { - ser: self, - state: State::Empty, - }) - } else { - tri!(self - .formatter - .begin_array(&mut self.writer) - .map_err(Error::io)); - Ok(Compound::Map { - ser: self, - state: State::First, - }) - } - } - - #[inline] - fn serialize_tuple(self, len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - #[inline] - fn serialize_tuple_struct( - self, - _name: &'static str, - len: usize, - ) -> Result { - self.serialize_seq(Some(len)) - } - - #[inline] - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - len: usize, - ) -> Result { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); - self.serialize_seq(Some(len)) - } - - #[inline] - fn serialize_map(self, len: Option) -> Result { - if len == Some(0) { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .end_object(&mut self.writer) - .map_err(Error::io)); - Ok(Compound::Map { - ser: self, - state: State::Empty, - }) - } else { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - Ok(Compound::Map { - ser: self, - state: State::First, - }) - } - } - - #[inline] - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - match name { - #[cfg(feature = "arbitrary_precision")] - crate::number::TOKEN => Ok(Compound::Number { ser: self }), - #[cfg(feature = "raw_value")] - crate::raw::TOKEN => Ok(Compound::RawValue { ser: self }), - _ => self.serialize_map(Some(len)), - } - } - - #[inline] - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - len: usize, - ) -> Result { - tri!(self - .formatter - .begin_object(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_key(&mut self.writer, true) - .map_err(Error::io)); - tri!(self.serialize_str(variant)); - tri!(self - .formatter - .end_object_key(&mut self.writer) - .map_err(Error::io)); - tri!(self - .formatter - .begin_object_value(&mut self.writer) - .map_err(Error::io)); - self.serialize_map(Some(len)) - } - - fn collect_str(self, value: &T) -> Result<()> - where - T: ?Sized + Display, - { - use self::fmt::Write; - - struct Adapter<'ser, W: 'ser, F: 'ser> { - writer: &'ser mut W, - formatter: &'ser mut F, - error: Option, - } - - impl<'ser, W, F> Write for Adapter<'ser, W, F> - where - W: io::Write, - F: Formatter, - { - fn write_str(&mut self, s: &str) -> fmt::Result { - debug_assert!(self.error.is_none()); - match format_escaped_str_contents(self.writer, self.formatter, s) { - Ok(()) => Ok(()), - Err(err) => { - self.error = Some(err); - Err(fmt::Error) - } - } - } - } - - tri!(self - .formatter - .begin_string(&mut self.writer) - .map_err(Error::io)); - { - let mut adapter = Adapter { - writer: &mut self.writer, - formatter: &mut self.formatter, - error: None, - }; - match write!(adapter, "{}", value) { - Ok(()) => debug_assert!(adapter.error.is_none()), - Err(fmt::Error) => { - return Err(Error::io(adapter.error.expect("there should be an error"))); - } - } - } - tri!(self - .formatter - .end_string(&mut self.writer) - .map_err(Error::io)); - Ok(()) - } -} - -// Not public API. Should be pub(crate). -#[doc(hidden)] -#[derive(Eq, PartialEq)] -pub enum State { - Empty, - First, - Rest, -} - -// Not public API. Should be pub(crate). -#[doc(hidden)] -pub enum Compound<'a, W: 'a, F: 'a> { - Map { - ser: &'a mut Serializer, - state: State, - }, - #[cfg(feature = "arbitrary_precision")] - Number { ser: &'a mut Serializer }, - #[cfg(feature = "raw_value")] - RawValue { ser: &'a mut Serializer }, -} - -impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_element(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - Compound::Map { - ref mut ser, - ref mut 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 - .end_array_value(&mut ser.writer) - .map_err(Error::io)); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } - - #[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(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } -} - -impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_element(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - ser::SerializeSeq::serialize_element(self, value) - } - - #[inline] - fn end(self) -> Result<()> { - ser::SerializeSeq::end(self) - } -} - -impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_field(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - ser::SerializeSeq::serialize_element(self, value) - } - - #[inline] - fn end(self) -> Result<()> { - ser::SerializeSeq::end(self) - } -} - -impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_field(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - ser::SerializeSeq::serialize_element(self, value) - } - - #[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)), - } - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } -} - -impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_key(&mut self, key: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - Compound::Map { - ref mut ser, - ref mut state, - } => { - tri!(ser - .formatter - .begin_object_key(&mut ser.writer, *state == State::First) - .map_err(Error::io)); - *state = State::Rest; - - tri!(key.serialize(MapKeySerializer { ser: *ser })); - - tri!(ser - .formatter - .end_object_key(&mut ser.writer) - .map_err(Error::io)); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } - - #[inline] - fn serialize_value(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - Compound::Map { ref mut ser, .. } => { - tri!(ser - .formatter - .begin_object_value(&mut ser.writer) - .map_err(Error::io)); - tri!(value.serialize(&mut **ser)); - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } - - #[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(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } -} - -impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - Compound::Map { .. } => ser::SerializeMap::serialize_entry(self, key, value), - #[cfg(feature = "arbitrary_precision")] - Compound::Number { ref mut ser, .. } => { - if key == crate::number::TOKEN { - tri!(value.serialize(NumberStrEmitter(&mut *ser))); - Ok(()) - } else { - Err(invalid_number()) - } - } - #[cfg(feature = "raw_value")] - Compound::RawValue { ref mut ser, .. } => { - if key == crate::raw::TOKEN { - tri!(value.serialize(RawValueStrEmitter(&mut *ser))); - Ok(()) - } else { - Err(invalid_raw_value()) - } - } - } - } - - #[inline] - fn end(self) -> Result<()> { - match self { - Compound::Map { .. } => ser::SerializeMap::end(self), - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => Ok(()), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => Ok(()), - } - } -} - -impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value), - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } - - #[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)), - } - tri!(ser - .formatter - .end_object_value(&mut ser.writer) - .map_err(Error::io)); - tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - Compound::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - Compound::RawValue { .. } => unreachable!(), - } - } -} - -struct MapKeySerializer<'a, W: 'a, F: 'a> { - ser: &'a mut Serializer, -} - -#[cfg(feature = "arbitrary_precision")] -fn invalid_number() -> Error { - Error::syntax(ErrorCode::InvalidNumber, 0, 0) -} - -#[cfg(feature = "raw_value")] -fn invalid_raw_value() -> Error { - Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) -} - -fn key_must_be_a_string() -> Error { - Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) -} - -impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> -where - W: io::Write, - F: Formatter, -{ - type Ok = (); - type Error = Error; - - #[inline] - fn serialize_str(self, value: &str) -> Result<()> { - self.ser.serialize_str(value) - } - - #[inline] - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - ) -> Result<()> { - self.ser.serialize_str(variant) - } - - #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - type SerializeSeq = Impossible<(), Error>; - type SerializeTuple = Impossible<(), Error>; - type SerializeTupleStruct = Impossible<(), Error>; - type SerializeTupleVariant = Impossible<(), Error>; - type SerializeMap = Impossible<(), Error>; - type SerializeStruct = Impossible<(), Error>; - type SerializeStructVariant = Impossible<(), Error>; - - fn serialize_bool(self, _value: bool) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_i8(self, value: i8) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_i8(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_i16(self, value: i16) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_i16(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_i32(self, value: i32) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_i32(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_i64(self, value: i64) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_i64(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - 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_u8(self, value: u8) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_u8(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_u16(self, value: u16) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_u16(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_u32(self, value: u32) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_u32(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - fn serialize_u64(self, value: u64) -> Result<()> { - tri!(self - .ser - .formatter - .begin_string(&mut self.ser.writer) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .write_u64(&mut self.ser.writer, value) - .map_err(Error::io)); - tri!(self - .ser - .formatter - .end_string(&mut self.ser.writer) - .map_err(Error::io)); - Ok(()) - } - - 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_f32(self, _value: f32) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_f64(self, _value: f64) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_char(self, value: char) -> Result<()> { - self.ser.serialize_str(&value.to_string()) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_unit(self) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(key_must_be_a_string()) - } - - fn serialize_none(self) -> Result<()> { - Err(key_must_be_a_string()) - } - - fn serialize_some(self, _value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(key_must_be_a_string()) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn collect_str(self, value: &T) -> Result<()> - where - T: ?Sized + Display, - { - self.ser.collect_str(value) - } -} - -#[cfg(feature = "arbitrary_precision")] -struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer); - -#[cfg(feature = "arbitrary_precision")] -impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> { - type Ok = (); - type Error = Error; - - type SerializeSeq = Impossible<(), Error>; - type SerializeTuple = Impossible<(), Error>; - type SerializeTupleStruct = Impossible<(), Error>; - type SerializeTupleVariant = Impossible<(), Error>; - type SerializeMap = Impossible<(), Error>; - type SerializeStruct = Impossible<(), Error>; - type SerializeStructVariant = Impossible<(), Error>; - - fn serialize_bool(self, _v: bool) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_i8(self, _v: i8) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_i16(self, _v: i16) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_i32(self, _v: i32) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_i64(self, _v: i64) -> Result<()> { - Err(invalid_number()) - } - - serde_if_integer128! { - fn serialize_i128(self, _v: i128) -> Result<()> { - Err(invalid_number()) - } - } - - fn serialize_u8(self, _v: u8) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_u16(self, _v: u16) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_u32(self, _v: u32) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_u64(self, _v: u64) -> Result<()> { - Err(invalid_number()) - } - - serde_if_integer128! { - fn serialize_u128(self, _v: u128) -> Result<()> { - Err(invalid_number()) - } - } - - fn serialize_f32(self, _v: f32) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_f64(self, _v: f64) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_char(self, _v: char) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_str(self, value: &str) -> Result<()> { - let NumberStrEmitter(serializer) = self; - serializer - .formatter - .write_number_str(&mut serializer.writer, value) - .map_err(Error::io) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_none(self) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_some(self, _value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_unit(self) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> Result<()> { - Err(invalid_number()) - } - - fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(invalid_number()) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(invalid_number()) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } -} - -#[cfg(feature = "raw_value")] -struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer); - -#[cfg(feature = "raw_value")] -impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> { - type Ok = (); - type Error = Error; - - type SerializeSeq = Impossible<(), Error>; - type SerializeTuple = Impossible<(), Error>; - type SerializeTupleStruct = Impossible<(), Error>; - type SerializeTupleVariant = Impossible<(), Error>; - type SerializeMap = Impossible<(), Error>; - type SerializeStruct = Impossible<(), Error>; - type SerializeStructVariant = Impossible<(), Error>; - - fn serialize_bool(self, _v: bool) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_i8(self, _v: i8) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_i16(self, _v: i16) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_i32(self, _v: i32) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_i64(self, _v: i64) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - serde_if_integer128! { - fn serialize_i128(self, _v: i128) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - } - - fn serialize_u8(self, _v: u8) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_u16(self, _v: u16) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_u32(self, _v: u32) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_u64(self, _v: u64) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - serde_if_integer128! { - fn serialize_u128(self, _v: u128) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - } - - fn serialize_f32(self, _v: f32) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_f64(self, _v: f64) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_char(self, _v: char) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_str(self, value: &str) -> Result<()> { - let RawValueStrEmitter(serializer) = self; - serializer - .formatter - .write_raw_fragment(&mut serializer.writer, value) - .map_err(Error::io) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_none(self) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_some(self, _value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_unit(self) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> Result<()> { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result<()> - where - T: ?Sized + Serialize, - { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(ser::Error::custom("expected RawValue")) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(ser::Error::custom("expected RawValue")) - } -} - -/// Represents a character escape code in a type-safe manner. -pub enum CharEscape { - /// An escaped quote `"` - Quote, - /// An escaped reverse solidus `\` - ReverseSolidus, - /// An escaped solidus `/` - Solidus, - /// An escaped backspace character (usually escaped as `\b`) - Backspace, - /// An escaped form feed character (usually escaped as `\f`) - FormFeed, - /// An escaped line feed character (usually escaped as `\n`) - LineFeed, - /// An escaped carriage return character (usually escaped as `\r`) - CarriageReturn, - /// An escaped tab character (usually escaped as `\t`) - Tab, - /// An escaped ASCII plane control character (usually escaped as - /// `\u00XX` where `XX` are two hex characters) - AsciiControl(u8), -} - -impl CharEscape { - #[inline] - fn from_escape_table(escape: u8, byte: u8) -> CharEscape { - match escape { - self::BB => CharEscape::Backspace, - self::TT => CharEscape::Tab, - self::NN => CharEscape::LineFeed, - self::FF => CharEscape::FormFeed, - self::RR => CharEscape::CarriageReturn, - self::QU => CharEscape::Quote, - self::BS => CharEscape::ReverseSolidus, - self::UU => CharEscape::AsciiControl(byte), - _ => unreachable!(), - } - } -} - -/// This trait abstracts away serializing the JSON control characters, which allows the user to -/// optionally pretty print the JSON output. -pub trait Formatter { - /// Writes a `null` value to the specified writer. - #[inline] - fn write_null(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"null") - } - - /// Writes a `true` or `false` value to the specified writer. - #[inline] - fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - let s = if value { - b"true" as &[u8] - } else { - b"false" as &[u8] - }; - writer.write_all(s) - } - - /// Writes an integer value like `-123` to the specified writer. - #[inline] - fn write_i8(&mut self, writer: &mut W, value: i8) -> 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_i16(&mut self, writer: &mut W, value: i16) -> 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_i32(&mut self, writer: &mut W, value: i32) -> 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_i64(&mut self, writer: &mut W, value: i64) -> 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(&mut self, writer: &mut W, value: u8) -> 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_u16(&mut self, writer: &mut W, value: u16) -> 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_u32(&mut self, writer: &mut W, value: u32) -> 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_u64(&mut self, writer: &mut W, value: u64) -> 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(&mut self, writer: &mut W, value: f32) -> io::Result<()> - where - W: ?Sized + io::Write, - { - let mut buffer = ryu::Buffer::new(); - let s = buffer.format_finite(value); - writer.write_all(s.as_bytes()) - } - - /// Writes a floating point value like `-31.26e+12` to the specified writer. - #[inline] - fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> - where - W: ?Sized + io::Write, - { - let mut buffer = ryu::Buffer::new(); - let s = buffer.format_finite(value); - writer.write_all(s.as_bytes()) - } - - /// Writes a number that has already been rendered to a string. - #[inline] - fn write_number_str(&mut self, writer: &mut W, value: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(value.as_bytes()) - } - - /// Called before each series of `write_string_fragment` and - /// `write_char_escape`. Writes a `"` to the specified writer. - #[inline] - fn begin_string(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"\"") - } - - /// Called after each series of `write_string_fragment` and - /// `write_char_escape`. Writes a `"` to the specified writer. - #[inline] - fn end_string(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"\"") - } - - /// Writes a string fragment that doesn't need any escaping to the - /// specified writer. - #[inline] - fn write_string_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(fragment.as_bytes()) - } - - /// Writes a character escape code to the specified writer. - #[inline] - fn write_char_escape(&mut self, writer: &mut W, char_escape: CharEscape) -> io::Result<()> - where - W: ?Sized + io::Write, - { - use self::CharEscape::*; - - let s = match char_escape { - Quote => b"\\\"", - ReverseSolidus => b"\\\\", - Solidus => b"\\/", - Backspace => b"\\b", - FormFeed => b"\\f", - LineFeed => b"\\n", - CarriageReturn => b"\\r", - Tab => b"\\t", - AsciiControl(byte) => { - static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; - let bytes = &[ - b'\\', - b'u', - b'0', - b'0', - HEX_DIGITS[(byte >> 4) as usize], - HEX_DIGITS[(byte & 0xF) as usize], - ]; - return writer.write_all(bytes); - } - }; - - writer.write_all(s) - } - - /// Called before every array. Writes a `[` to the specified - /// writer. - #[inline] - fn begin_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"[") - } - - /// Called after every array. Writes a `]` to the specified - /// writer. - #[inline] - fn end_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"]") - } - - /// Called before every array value. Writes a `,` if needed to - /// the specified writer. - #[inline] - fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - if first { - Ok(()) - } else { - writer.write_all(b",") - } - } - - /// Called after every array value. - #[inline] - fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - Ok(()) - } - - /// Called before every object. Writes a `{` to the specified - /// writer. - #[inline] - fn begin_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"{") - } - - /// Called after every object. Writes a `}` to the specified - /// writer. - #[inline] - fn end_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b"}") - } - - /// Called before every object key. - #[inline] - fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - if first { - Ok(()) - } else { - writer.write_all(b",") - } - } - - /// Called after every object key. A `:` should be written to the - /// specified writer by either this method or - /// `begin_object_value`. - #[inline] - fn end_object_key(&mut self, _writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - Ok(()) - } - - /// Called before every object value. A `:` should be written to - /// the specified writer by either this method or - /// `end_object_key`. - #[inline] - fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b":") - } - - /// Called after every object value. - #[inline] - fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - Ok(()) - } - - /// Writes a raw JSON fragment that doesn't need any escaping to the - /// specified writer. - #[inline] - fn write_raw_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(fragment.as_bytes()) - } -} - -/// This structure compacts a JSON value with no extra whitespace. -#[derive(Clone, Debug)] -pub struct CompactFormatter; - -impl Formatter for CompactFormatter {} - -/// This structure pretty prints a JSON value to make it human readable. -#[derive(Clone, Debug)] -pub struct PrettyFormatter<'a> { - current_indent: usize, - has_value: bool, - indent: &'a [u8], -} - -impl<'a> PrettyFormatter<'a> { - /// Construct a pretty printer formatter that defaults to using two spaces for indentation. - pub fn new() -> Self { - PrettyFormatter::with_indent(b" ") - } - - /// Construct a pretty printer formatter that uses the `indent` string for indentation. - pub fn with_indent(indent: &'a [u8]) -> Self { - PrettyFormatter { - current_indent: 0, - has_value: false, - indent: indent, - } - } -} - -impl<'a> Default for PrettyFormatter<'a> { - fn default() -> Self { - PrettyFormatter::new() - } -} - -impl<'a> Formatter for PrettyFormatter<'a> { - #[inline] - fn begin_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.current_indent += 1; - self.has_value = false; - writer.write_all(b"[") - } - - #[inline] - fn end_array(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.current_indent -= 1; - - if self.has_value { - tri!(writer.write_all(b"\n")); - tri!(indent(writer, self.current_indent, self.indent)); - } - - writer.write_all(b"]") - } - - #[inline] - fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> - 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(()) - } - - #[inline] - fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.has_value = true; - Ok(()) - } - - #[inline] - fn begin_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.current_indent += 1; - self.has_value = false; - writer.write_all(b"{") - } - - #[inline] - fn end_object(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.current_indent -= 1; - - if self.has_value { - tri!(writer.write_all(b"\n")); - tri!(indent(writer, self.current_indent, self.indent)); - } - - writer.write_all(b"}") - } - - #[inline] - fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> - where - W: ?Sized + io::Write, - { - if first { - tri!(writer.write_all(b"\n")); - } else { - tri!(writer.write_all(b",\n")); - } - indent(writer, self.current_indent, self.indent) - } - - #[inline] - fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - writer.write_all(b": ") - } - - #[inline] - fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> - where - W: ?Sized + io::Write, - { - self.has_value = true; - Ok(()) - } -} - -fn format_escaped_str(writer: &mut W, formatter: &mut F, value: &str) -> io::Result<()> -where - W: ?Sized + io::Write, - F: ?Sized + Formatter, -{ - tri!(formatter.begin_string(writer)); - tri!(format_escaped_str_contents(writer, formatter, value)); - tri!(formatter.end_string(writer)); - Ok(()) -} - -fn format_escaped_str_contents( - writer: &mut W, - formatter: &mut F, - value: &str, -) -> io::Result<()> -where - W: ?Sized + io::Write, - F: ?Sized + Formatter, -{ - let bytes = value.as_bytes(); - - let mut start = 0; - - for (i, &byte) in bytes.iter().enumerate() { - let escape = ESCAPE[byte as usize]; - if escape == 0 { - continue; - } - - if start < i { - tri!(formatter.write_string_fragment(writer, &value[start..i])); - } - - let char_escape = CharEscape::from_escape_table(escape, byte); - tri!(formatter.write_char_escape(writer, char_escape)); - - start = i + 1; - } - - if start != bytes.len() { - tri!(formatter.write_string_fragment(writer, &value[start..])); - } - - Ok(()) -} - -const BB: u8 = b'b'; // \x08 -const TT: u8 = b't'; // \x09 -const NN: u8 = b'n'; // \x0A -const FF: u8 = b'f'; // \x0C -const RR: u8 = b'r'; // \x0D -const QU: u8 = b'"'; // \x22 -const BS: u8 = b'\\'; // \x5C -const UU: u8 = b'u'; // \x00...\x1F except the ones above -const __: u8 = 0; - -// Lookup table of escape sequences. A value of b'x' at index i means that byte -// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped. -static ESCAPE: [u8; 256] = [ - // 1 2 3 4 5 6 7 8 9 A B C D E F - UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0 - UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1 - __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4 - __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9 - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F -]; - -/// Serialize the given data structure as JSON into the IO stream. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_writer(writer: W, value: &T) -> Result<()> -where - W: io::Write, - T: ?Sized + Serialize, -{ - let mut ser = Serializer::new(writer); - tri!(value.serialize(&mut ser)); - Ok(()) -} - -/// Serialize the given data structure as pretty-printed JSON into the IO -/// stream. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_writer_pretty(writer: W, value: &T) -> Result<()> -where - W: io::Write, - T: ?Sized + Serialize, -{ - let mut ser = Serializer::pretty(writer); - tri!(value.serialize(&mut ser)); - Ok(()) -} - -/// Serialize the given data structure as a JSON byte vector. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_vec(value: &T) -> Result> -where - T: ?Sized + Serialize, -{ - let mut writer = Vec::with_capacity(128); - tri!(to_writer(&mut writer, value)); - Ok(writer) -} - -/// Serialize the given data structure as a pretty-printed JSON byte vector. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_vec_pretty(value: &T) -> Result> -where - T: ?Sized + Serialize, -{ - let mut writer = Vec::with_capacity(128); - tri!(to_writer_pretty(&mut writer, value)); - Ok(writer) -} - -/// Serialize the given data structure as a String of JSON. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_string(value: &T) -> Result -where - T: ?Sized + Serialize, -{ - let vec = tri!(to_vec(value)); - let string = unsafe { - // We do not emit invalid UTF-8. - String::from_utf8_unchecked(vec) - }; - Ok(string) -} - -/// Serialize the given data structure as a pretty-printed String of JSON. -/// -/// # Errors -/// -/// Serialization can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -#[inline] -pub fn to_string_pretty(value: &T) -> Result -where - T: ?Sized + Serialize, -{ - let vec = tri!(to_vec_pretty(value)); - let string = unsafe { - // We do not emit invalid UTF-8. - String::from_utf8_unchecked(vec) - }; - Ok(string) -} - -fn indent(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()> -where - W: ?Sized + io::Write, -{ - for _ in 0..n { - tri!(wr.write_all(s)); - } - - Ok(()) -} diff --git a/json/src/value/de.rs b/json/src/value/de.rs deleted file mode 100644 index d9ef592d..00000000 --- a/json/src/value/de.rs +++ /dev/null @@ -1,1482 +0,0 @@ -use crate::error::Error; -use crate::lib::str::FromStr; -use crate::lib::*; -use crate::map::Map; -use crate::number::Number; -use crate::value::Value; -use serde::de::{ - self, Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess, - SeqAccess, Unexpected, VariantAccess, Visitor, -}; -use serde::{forward_to_deserialize_any, serde_if_integer128}; - -#[cfg(feature = "arbitrary_precision")] -use crate::number::NumberFromString; - -impl<'de> Deserialize<'de> for Value { - #[inline] - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - struct ValueVisitor; - - impl<'de> Visitor<'de> for ValueVisitor { - type Value = Value; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("any valid JSON value") - } - - #[inline] - fn visit_bool(self, value: bool) -> Result { - Ok(Value::Bool(value)) - } - - #[inline] - fn visit_i64(self, value: i64) -> Result { - Ok(Value::Number(value.into())) - } - - #[inline] - fn visit_u64(self, value: u64) -> Result { - Ok(Value::Number(value.into())) - } - - #[inline] - fn visit_f64(self, value: f64) -> Result { - Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) - } - - #[cfg(any(feature = "std", feature = "alloc"))] - #[inline] - fn visit_str(self, value: &str) -> Result - where - E: serde::de::Error, - { - self.visit_string(String::from(value)) - } - - #[cfg(any(feature = "std", feature = "alloc"))] - #[inline] - fn visit_string(self, value: String) -> Result { - Ok(Value::String(value)) - } - - #[inline] - fn visit_none(self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_some(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - Deserialize::deserialize(deserializer) - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result - where - V: SeqAccess<'de>, - { - let mut vec = Vec::new(); - - while let Some(elem) = tri!(visitor.next_element()) { - vec.push(elem); - } - - Ok(Value::Array(vec)) - } - - #[cfg(any(feature = "std", feature = "alloc"))] - fn visit_map(self, mut visitor: V) -> Result - where - V: MapAccess<'de>, - { - match visitor.next_key_seed(KeyClassifier)? { - #[cfg(feature = "arbitrary_precision")] - Some(KeyClass::Number) => { - let number: NumberFromString = visitor.next_value()?; - Ok(Value::Number(number.value)) - } - #[cfg(feature = "raw_value")] - Some(KeyClass::RawValue) => { - let value = visitor.next_value_seed(crate::raw::BoxedFromString)?; - crate::from_str(value.get()).map_err(de::Error::custom) - } - Some(KeyClass::Map(first_key)) => { - let mut values = Map::new(); - - values.insert(first_key, tri!(visitor.next_value())); - while let Some((key, value)) = tri!(visitor.next_entry()) { - values.insert(key, value); - } - - Ok(Value::Object(values)) - } - None => Ok(Value::Object(Map::new())), - } - } - } - - deserializer.deserialize_any(ValueVisitor) - } -} - -impl FromStr for Value { - type Err = Error; - fn from_str(s: &str) -> Result { - super::super::de::from_str(s) - } -} - -macro_rules! deserialize_prim_number { - ($method:ident) => { - #[cfg(not(feature = "arbitrary_precision"))] - fn $method(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Number(n) => n.deserialize_any(visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn $method(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Number(n) => n.$method(visitor), - _ => self.deserialize_any(visitor), - } - } - }; -} - -fn visit_array<'de, V>(array: Vec, visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = array.len(); - let mut deserializer = SeqDeserializer::new(array); - let seq = tri!(visitor.visit_seq(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(seq) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in array", - )) - } -} - -fn visit_object<'de, V>(object: Map, visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = object.len(); - let mut deserializer = MapDeserializer::new(object); - let map = tri!(visitor.visit_map(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(map) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in map", - )) - } -} - -impl<'de> serde::Deserializer<'de> for Value { - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Null => visitor.visit_unit(), - Value::Bool(v) => visitor.visit_bool(v), - Value::Number(n) => n.deserialize_any(visitor), - #[cfg(any(feature = "std", feature = "alloc"))] - Value::String(v) => visitor.visit_string(v), - Value::Array(v) => visit_array(v, visitor), - Value::Object(v) => visit_object(v, visitor), - } - } - - deserialize_prim_number!(deserialize_i8); - deserialize_prim_number!(deserialize_i16); - deserialize_prim_number!(deserialize_i32); - deserialize_prim_number!(deserialize_i64); - deserialize_prim_number!(deserialize_u8); - deserialize_prim_number!(deserialize_u16); - deserialize_prim_number!(deserialize_u32); - deserialize_prim_number!(deserialize_u64); - deserialize_prim_number!(deserialize_f32); - deserialize_prim_number!(deserialize_f64); - - serde_if_integer128! { - deserialize_prim_number!(deserialize_i128); - deserialize_prim_number!(deserialize_u128); - } - - #[inline] - fn deserialize_option(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Null => visitor.visit_none(), - _ => visitor.visit_some(self), - } - } - - #[inline] - fn deserialize_enum( - self, - _name: &str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - let (variant, value) = match self { - Value::Object(value) => { - let mut iter = value.into_iter(); - let (variant, value) = match iter.next() { - Some(v) => v, - None => { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - (variant, Some(value)) - } - Value::String(variant) => (variant, None), - other => { - return Err(serde::de::Error::invalid_type( - other.unexpected(), - &"string or map", - )); - } - }; - - visitor.visit_enum(EnumDeserializer { - variant: variant, - value: value, - }) - } - - #[inline] - fn deserialize_newtype_struct( - self, - name: &'static str, - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - #[cfg(feature = "raw_value")] - { - if name == crate::raw::TOKEN { - return visitor.visit_map(crate::raw::OwnedRawDeserializer { - raw_value: Some(self.to_string()), - }); - } - } - - let _ = name; - visitor.visit_newtype_struct(self) - } - - fn deserialize_bool(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Bool(v) => visitor.visit_bool(v), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_char(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_string(visitor) - } - - fn deserialize_str(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_string(visitor) - } - - fn deserialize_string(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - #[cfg(any(feature = "std", feature = "alloc"))] - Value::String(v) => visitor.visit_string(v), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_bytes(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_byte_buf(visitor) - } - - fn deserialize_byte_buf(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - #[cfg(any(feature = "std", feature = "alloc"))] - Value::String(v) => visitor.visit_string(v), - Value::Array(v) => visit_array(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_unit(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Null => visitor.visit_unit(), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_unit(visitor) - } - - fn deserialize_seq(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Array(v) => visit_array(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_tuple(self, _len: usize, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_map(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Object(v) => visit_object(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_struct( - self, - _name: &'static str, - _fields: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - match self { - Value::Array(v) => visit_array(v, visitor), - Value::Object(v) => visit_object(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_identifier(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_string(visitor) - } - - fn deserialize_ignored_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - drop(self); - visitor.visit_unit() - } -} - -struct EnumDeserializer { - variant: String, - value: Option, -} - -impl<'de> EnumAccess<'de> for EnumDeserializer { - type Error = Error; - type Variant = VariantDeserializer; - - fn variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> - where - V: DeserializeSeed<'de>, - { - let variant = self.variant.into_deserializer(); - let visitor = VariantDeserializer { value: self.value }; - seed.deserialize(variant).map(|v| (v, visitor)) - } -} - -impl<'de> IntoDeserializer<'de, Error> for Value { - type Deserializer = Self; - - fn into_deserializer(self) -> Self::Deserializer { - self - } -} - -struct VariantDeserializer { - value: Option, -} - -impl<'de> VariantAccess<'de> for VariantDeserializer { - type Error = Error; - - fn unit_variant(self) -> Result<(), Error> { - match self.value { - Some(value) => Deserialize::deserialize(value), - None => Ok(()), - } - } - - fn newtype_variant_seed(self, seed: T) -> Result - where - T: DeserializeSeed<'de>, - { - match self.value { - Some(value) => seed.deserialize(value), - None => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"newtype variant", - )), - } - } - - fn tuple_variant(self, _len: usize, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self.value { - Some(Value::Array(v)) => { - serde::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) - } - Some(other) => Err(serde::de::Error::invalid_type( - other.unexpected(), - &"tuple variant", - )), - None => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"tuple variant", - )), - } - } - - fn struct_variant( - self, - _fields: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - match self.value { - Some(Value::Object(v)) => { - serde::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) - } - Some(other) => Err(serde::de::Error::invalid_type( - other.unexpected(), - &"struct variant", - )), - _ => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"struct variant", - )), - } - } -} - -struct SeqDeserializer { - iter: vec::IntoIter, -} - -impl SeqDeserializer { - fn new(vec: Vec) -> Self { - SeqDeserializer { - iter: vec.into_iter(), - } - } -} - -impl<'de> serde::Deserializer<'de> for SeqDeserializer { - type Error = Error; - - #[inline] - fn deserialize_any(mut self, visitor: V) -> Result - where - V: Visitor<'de>, - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = tri!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in array", - )) - } - } - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } -} - -impl<'de> SeqAccess<'de> for SeqDeserializer { - type Error = Error; - - fn next_element_seed(&mut self, seed: T) -> Result, Error> - where - T: DeserializeSeed<'de>, - { - match self.iter.next() { - Some(value) => seed.deserialize(value).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> Option { - match self.iter.size_hint() { - (lower, Some(upper)) if lower == upper => Some(upper), - _ => None, - } - } -} - -struct MapDeserializer { - iter: as IntoIterator>::IntoIter, - value: Option, -} - -impl MapDeserializer { - fn new(map: Map) -> Self { - MapDeserializer { - iter: map.into_iter(), - value: None, - } - } -} - -impl<'de> MapAccess<'de> for MapDeserializer { - type Error = Error; - - fn next_key_seed(&mut self, seed: T) -> Result, Error> - where - T: DeserializeSeed<'de>, - { - match self.iter.next() { - Some((key, value)) => { - self.value = Some(value); - let key_de = MapKeyDeserializer { - key: Cow::Owned(key), - }; - seed.deserialize(key_de).map(Some) - } - None => Ok(None), - } - } - - fn next_value_seed(&mut self, seed: T) -> Result - where - T: DeserializeSeed<'de>, - { - match self.value.take() { - Some(value) => seed.deserialize(value), - None => Err(serde::de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> Option { - match self.iter.size_hint() { - (lower, Some(upper)) if lower == upper => Some(upper), - _ => None, - } - } -} - -impl<'de> serde::Deserializer<'de> for MapDeserializer { - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - visitor.visit_map(self) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } -} - -macro_rules! deserialize_value_ref_number { - ($method:ident) => { - #[cfg(not(feature = "arbitrary_precision"))] - fn $method(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Number(ref n) => n.deserialize_any(visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - #[cfg(feature = "arbitrary_precision")] - fn $method(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Number(ref n) => n.$method(visitor), - _ => self.deserialize_any(visitor), - } - } - }; -} - -fn visit_array_ref<'de, V>(array: &'de [Value], visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = array.len(); - let mut deserializer = SeqRefDeserializer::new(array); - let seq = tri!(visitor.visit_seq(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(seq) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in array", - )) - } -} - -fn visit_object_ref<'de, V>(object: &'de Map, visitor: V) -> Result -where - V: Visitor<'de>, -{ - let len = object.len(); - let mut deserializer = MapRefDeserializer::new(object); - let map = tri!(visitor.visit_map(&mut deserializer)); - let remaining = deserializer.iter.len(); - if remaining == 0 { - Ok(map) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in map", - )) - } -} - -impl<'de> serde::Deserializer<'de> for &'de Value { - type Error = Error; - - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - 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), - } - } - - deserialize_value_ref_number!(deserialize_i8); - deserialize_value_ref_number!(deserialize_i16); - deserialize_value_ref_number!(deserialize_i32); - deserialize_value_ref_number!(deserialize_i64); - 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_value_ref_number!(deserialize_f32); - deserialize_value_ref_number!(deserialize_f64); - - serde_if_integer128! { - deserialize_prim_number!(deserialize_i128); - deserialize_prim_number!(deserialize_u128); - } - - fn deserialize_option(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Null => visitor.visit_none(), - _ => visitor.visit_some(self), - } - } - - fn deserialize_enum( - self, - _name: &str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - let (variant, value) = match *self { - Value::Object(ref value) => { - let mut iter = value.into_iter(); - let (variant, value) = match iter.next() { - Some(v) => v, - None => { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - }; - // enums are encoded in json as maps with a single key:value pair - if iter.next().is_some() { - return Err(serde::de::Error::invalid_value( - Unexpected::Map, - &"map with a single key", - )); - } - (variant, Some(value)) - } - Value::String(ref variant) => (variant, None), - ref other => { - return Err(serde::de::Error::invalid_type( - other.unexpected(), - &"string or map", - )); - } - }; - - visitor.visit_enum(EnumRefDeserializer { - variant: variant, - value: value, - }) - } - - #[inline] - fn deserialize_newtype_struct( - self, - name: &'static str, - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - #[cfg(feature = "raw_value")] - { - if name == crate::raw::TOKEN { - return visitor.visit_map(crate::raw::OwnedRawDeserializer { - raw_value: Some(self.to_string()), - }); - } - } - - let _ = name; - visitor.visit_newtype_struct(self) - } - - fn deserialize_bool(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Bool(v) => visitor.visit_bool(v), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_char(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_str(visitor) - } - - fn deserialize_str(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::String(ref v) => visitor.visit_borrowed_str(v), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_string(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_str(visitor) - } - - fn deserialize_bytes(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::String(ref v) => visitor.visit_borrowed_str(v), - Value::Array(ref v) => visit_array_ref(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_byte_buf(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_bytes(visitor) - } - - fn deserialize_unit(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Null => visitor.visit_unit(), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_unit(visitor) - } - - fn deserialize_seq(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Array(ref v) => visit_array_ref(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_tuple(self, _len: usize, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - self.deserialize_seq(visitor) - } - - fn deserialize_map(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Object(ref v) => visit_object_ref(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_struct( - self, - _name: &'static str, - _fields: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - match *self { - Value::Array(ref v) => visit_array_ref(v, visitor), - Value::Object(ref v) => visit_object_ref(v, visitor), - _ => Err(self.invalid_type(&visitor)), - } - } - - fn deserialize_identifier(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - self.deserialize_str(visitor) - } - - fn deserialize_ignored_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - visitor.visit_unit() - } -} - -struct EnumRefDeserializer<'de> { - variant: &'de str, - value: Option<&'de Value>, -} - -impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { - type Error = Error; - type Variant = VariantRefDeserializer<'de>; - - fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Error> - where - V: DeserializeSeed<'de>, - { - let variant = self.variant.into_deserializer(); - let visitor = VariantRefDeserializer { value: self.value }; - seed.deserialize(variant).map(|v| (v, visitor)) - } -} - -struct VariantRefDeserializer<'de> { - value: Option<&'de Value>, -} - -impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { - type Error = Error; - - fn unit_variant(self) -> Result<(), Error> { - match self.value { - Some(value) => Deserialize::deserialize(value), - None => Ok(()), - } - } - - fn newtype_variant_seed(self, seed: T) -> Result - where - T: DeserializeSeed<'de>, - { - match self.value { - Some(value) => seed.deserialize(value), - None => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"newtype variant", - )), - } - } - - fn tuple_variant(self, _len: usize, visitor: V) -> Result - where - V: Visitor<'de>, - { - match self.value { - Some(&Value::Array(ref v)) => { - serde::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) - } - Some(other) => Err(serde::de::Error::invalid_type( - other.unexpected(), - &"tuple variant", - )), - None => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"tuple variant", - )), - } - } - - fn struct_variant( - self, - _fields: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - match self.value { - Some(&Value::Object(ref v)) => { - serde::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) - } - Some(other) => Err(serde::de::Error::invalid_type( - other.unexpected(), - &"struct variant", - )), - _ => Err(serde::de::Error::invalid_type( - Unexpected::UnitVariant, - &"struct variant", - )), - } - } -} - -struct SeqRefDeserializer<'de> { - iter: slice::Iter<'de, Value>, -} - -impl<'de> SeqRefDeserializer<'de> { - fn new(slice: &'de [Value]) -> Self { - SeqRefDeserializer { iter: slice.iter() } - } -} - -impl<'de> serde::Deserializer<'de> for SeqRefDeserializer<'de> { - type Error = Error; - - #[inline] - fn deserialize_any(mut self, visitor: V) -> Result - where - V: Visitor<'de>, - { - let len = self.iter.len(); - if len == 0 { - visitor.visit_unit() - } else { - let ret = tri!(visitor.visit_seq(&mut self)); - let remaining = self.iter.len(); - if remaining == 0 { - Ok(ret) - } else { - Err(serde::de::Error::invalid_length( - len, - &"fewer elements in array", - )) - } - } - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } -} - -impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { - type Error = Error; - - fn next_element_seed(&mut self, seed: T) -> Result, Error> - where - T: DeserializeSeed<'de>, - { - match self.iter.next() { - Some(value) => seed.deserialize(value).map(Some), - None => Ok(None), - } - } - - fn size_hint(&self) -> Option { - match self.iter.size_hint() { - (lower, Some(upper)) if lower == upper => Some(upper), - _ => None, - } - } -} - -struct MapRefDeserializer<'de> { - iter: <&'de Map as IntoIterator>::IntoIter, - value: Option<&'de Value>, -} - -impl<'de> MapRefDeserializer<'de> { - fn new(map: &'de Map) -> Self { - MapRefDeserializer { - iter: map.into_iter(), - value: None, - } - } -} - -impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { - type Error = Error; - - fn next_key_seed(&mut self, seed: T) -> Result, Error> - where - T: DeserializeSeed<'de>, - { - match self.iter.next() { - Some((key, value)) => { - self.value = Some(value); - let key_de = MapKeyDeserializer { - key: Cow::Borrowed(&**key), - }; - seed.deserialize(key_de).map(Some) - } - None => Ok(None), - } - } - - fn next_value_seed(&mut self, seed: T) -> Result - where - T: DeserializeSeed<'de>, - { - match self.value.take() { - Some(value) => seed.deserialize(value), - None => Err(serde::de::Error::custom("value is missing")), - } - } - - fn size_hint(&self) -> Option { - match self.iter.size_hint() { - (lower, Some(upper)) if lower == upper => Some(upper), - _ => None, - } - } -} - -impl<'de> serde::Deserializer<'de> for MapRefDeserializer<'de> { - type Error = Error; - - #[inline] - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - visitor.visit_map(self) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct enum identifier ignored_any - } -} - -struct MapKeyDeserializer<'de> { - key: Cow<'de, str>, -} - -macro_rules! deserialize_integer_key { - ($method:ident => $visit:ident) => { - fn $method(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - match (self.key.parse(), self.key) { - (Ok(integer), _) => visitor.$visit(integer), - (Err(_), Cow::Borrowed(s)) => visitor.visit_borrowed_str(s), - #[cfg(any(feature = "std", feature = "alloc"))] - (Err(_), Cow::Owned(s)) => visitor.visit_string(s), - } - } - }; -} - -impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { - type Error = Error; - - fn deserialize_any(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) - } - - deserialize_integer_key!(deserialize_i8 => visit_i8); - 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_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); - } - - #[inline] - fn deserialize_option(self, visitor: V) -> Result - where - V: Visitor<'de>, - { - // Map keys cannot be null. - visitor.visit_some(self) - } - - #[inline] - fn deserialize_newtype_struct( - self, - _name: &'static str, - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - visitor.visit_newtype_struct(self) - } - - fn deserialize_enum( - self, - name: &'static str, - variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: Visitor<'de>, - { - self.key - .into_deserializer() - .deserialize_enum(name, variants, visitor) - } - - forward_to_deserialize_any! { - bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple - tuple_struct map struct identifier ignored_any - } -} - -struct KeyClassifier; - -enum KeyClass { - Map(String), - #[cfg(feature = "arbitrary_precision")] - Number, - #[cfg(feature = "raw_value")] - RawValue, -} - -impl<'de> DeserializeSeed<'de> for KeyClassifier { - type Value = KeyClass; - - fn deserialize(self, deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_str(self) - } -} - -impl<'de> Visitor<'de> for KeyClassifier { - type Value = KeyClass; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a string key") - } - - fn visit_str(self, s: &str) -> Result - where - E: de::Error, - { - match s { - #[cfg(feature = "arbitrary_precision")] - crate::number::TOKEN => Ok(KeyClass::Number), - #[cfg(feature = "raw_value")] - crate::raw::TOKEN => Ok(KeyClass::RawValue), - _ => Ok(KeyClass::Map(s.to_owned())), - } - } - - #[cfg(any(feature = "std", feature = "alloc"))] - fn visit_string(self, s: String) -> Result - where - E: de::Error, - { - match s.as_str() { - #[cfg(feature = "arbitrary_precision")] - crate::number::TOKEN => Ok(KeyClass::Number), - #[cfg(feature = "raw_value")] - crate::raw::TOKEN => Ok(KeyClass::RawValue), - _ => Ok(KeyClass::Map(s)), - } - } -} - -impl Value { - #[cold] - fn invalid_type(&self, exp: &dyn Expected) -> E - where - E: serde::de::Error, - { - serde::de::Error::invalid_type(self.unexpected(), exp) - } - - #[cold] - fn unexpected(&self) -> Unexpected { - 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::Array(_) => Unexpected::Seq, - Value::Object(_) => Unexpected::Map, - } - } -} - -struct BorrowedCowStrDeserializer<'de> { - value: Cow<'de, str>, -} - -impl<'de> BorrowedCowStrDeserializer<'de> { - fn new(value: Cow<'de, str>) -> Self { - BorrowedCowStrDeserializer { value: value } - } -} - -impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> { - type Error = Error; - - fn deserialize_any(self, visitor: V) -> Result - where - V: de::Visitor<'de>, - { - match self.value { - Cow::Borrowed(string) => visitor.visit_borrowed_str(string), - #[cfg(any(feature = "std", feature = "alloc"))] - Cow::Owned(string) => visitor.visit_string(string), - } - } - - fn deserialize_enum( - self, - _name: &str, - _variants: &'static [&'static str], - visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - visitor.visit_enum(self) - } - - forward_to_deserialize_any! { - bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string - bytes byte_buf option unit unit_struct newtype_struct seq tuple - tuple_struct map struct identifier ignored_any - } -} - -impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { - type Error = Error; - type Variant = UnitOnly; - - fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Error> - where - T: de::DeserializeSeed<'de>, - { - let value = seed.deserialize(self)?; - Ok((value, UnitOnly)) - } -} - -struct UnitOnly; - -impl<'de> de::VariantAccess<'de> for UnitOnly { - type Error = Error; - - fn unit_variant(self) -> Result<(), Error> { - Ok(()) - } - - fn newtype_variant_seed(self, _seed: T) -> Result - where - T: de::DeserializeSeed<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"newtype variant", - )) - } - - fn tuple_variant(self, _len: usize, _visitor: V) -> Result - where - V: de::Visitor<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"tuple variant", - )) - } - - fn struct_variant( - self, - _fields: &'static [&'static str], - _visitor: V, - ) -> Result - where - V: de::Visitor<'de>, - { - Err(de::Error::invalid_type( - Unexpected::UnitVariant, - &"struct variant", - )) - } -} diff --git a/json/src/value/from.rs b/json/src/value/from.rs deleted file mode 100644 index 93d36541..00000000 --- a/json/src/value/from.rs +++ /dev/null @@ -1,232 +0,0 @@ -use super::Value; -use crate::lib::iter::FromIterator; -use crate::lib::*; -use crate::map::Map; -use crate::number::Number; - -#[cfg(feature = "arbitrary_precision")] -use serde::serde_if_integer128; - -macro_rules! from_integer { - ($($ty:ident)*) => { - $( - impl From<$ty> for Value { - fn from(n: $ty) -> Self { - Value::Number(n.into()) - } - } - )* - }; -} - -from_integer! { - i8 i16 i32 i64 isize - u8 u16 u32 u64 usize -} - -#[cfg(feature = "arbitrary_precision")] -serde_if_integer128! { - from_integer! { - i128 u128 - } -} - -impl From for Value { - /// Convert 32-bit floating point number to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let f: f32 = 13.37; - /// let x: Value = f.into(); - /// ``` - fn from(f: f32) -> Self { - From::from(f as f64) - } -} - -impl From for Value { - /// Convert 64-bit floating point number to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let f: f64 = 13.37; - /// let x: Value = f.into(); - /// ``` - fn from(f: f64) -> Self { - Number::from_f64(f).map_or(Value::Null, Value::Number) - } -} - -impl From for Value { - /// Convert boolean to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let b = false; - /// let x: Value = b.into(); - /// ``` - fn from(f: bool) -> Self { - Value::Bool(f) - } -} - -impl From for Value { - /// Convert `String` to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let s: String = "lorem".to_string(); - /// let x: Value = s.into(); - /// ``` - fn from(f: String) -> Self { - Value::String(f) - } -} - -impl<'a> From<&'a str> for Value { - /// Convert string slice to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let s: &str = "lorem"; - /// let x: Value = s.into(); - /// ``` - fn from(f: &str) -> Self { - Value::String(f.to_string()) - } -} - -impl<'a> From> for Value { - /// Convert copy-on-write string to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// use std::borrow::Cow; - /// - /// let s: Cow = Cow::Borrowed("lorem"); - /// let x: Value = s.into(); - /// ``` - /// - /// ``` - /// use serde_json::Value; - /// use std::borrow::Cow; - /// - /// let s: Cow = Cow::Owned("lorem".to_string()); - /// let x: Value = s.into(); - /// ``` - fn from(f: Cow<'a, str>) -> Self { - Value::String(f.into_owned()) - } -} - -impl From> for Value { - /// Convert map (with string keys) to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::{Map, Value}; - /// - /// let mut m = Map::new(); - /// m.insert("Lorem".to_string(), "ipsum".into()); - /// let x: Value = m.into(); - /// ``` - fn from(f: Map) -> Self { - Value::Object(f) - } -} - -impl> From> for Value { - /// Convert a `Vec` to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let v = vec!["lorem", "ipsum", "dolor"]; - /// let x: Value = v.into(); - /// ``` - fn from(f: Vec) -> Self { - Value::Array(f.into_iter().map(Into::into).collect()) - } -} - -impl<'a, T: Clone + Into> From<&'a [T]> for Value { - /// Convert a slice to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; - /// let x: Value = v.into(); - /// ``` - fn from(f: &'a [T]) -> Self { - Value::Array(f.iter().cloned().map(Into::into).collect()) - } -} - -impl> FromIterator for Value { - /// Convert an iteratable type to a `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let v = std::iter::repeat(42).take(5); - /// let x: Value = v.collect(); - /// ``` - /// - /// ``` - /// use serde_json::Value; - /// - /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; - /// let x: Value = v.into_iter().collect(); - /// ``` - /// - /// ``` - /// use std::iter::FromIterator; - /// use serde_json::Value; - /// - /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); - /// ``` - fn from_iter>(iter: I) -> Self { - Value::Array(iter.into_iter().map(Into::into).collect()) - } -} - -impl From<()> for Value { - /// Convert `()` to `Value` - /// - /// # Examples - /// - /// ``` - /// use serde_json::Value; - /// - /// let u = (); - /// let x: Value = u.into(); - /// ``` - fn from((): ()) -> Self { - Value::Null - } -} diff --git a/json/src/value/index.rs b/json/src/value/index.rs deleted file mode 100644 index d759a1df..00000000 --- a/json/src/value/index.rs +++ /dev/null @@ -1,255 +0,0 @@ -use super::Value; -use crate::lib::*; -use crate::map::Map; - -/// A type that can be used to index into a `serde_json::Value`. -/// -/// The [`get`] and [`get_mut`] methods of `Value` accept any type that -/// implements `Index`, as does the [square-bracket indexing operator]. This -/// trait is implemented for strings which are used as the index into a JSON -/// map, and for `usize` which is used as the index into a JSON array. -/// -/// [`get`]: ../enum.Value.html#method.get -/// [`get_mut`]: ../enum.Value.html#method.get_mut -/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E -/// -/// This trait is sealed and cannot be implemented for types outside of -/// `serde_json`. -/// -/// # Examples -/// -/// ``` -/// # use serde_json::json; -/// # -/// let data = json!({ "inner": [1, 2, 3] }); -/// -/// // Data is a JSON map so it can be indexed with a string. -/// let inner = &data["inner"]; -/// -/// // Inner is a JSON array so it can be indexed with an integer. -/// let first = &inner[0]; -/// -/// assert_eq!(first, 1); -/// ``` -pub trait Index: private::Sealed { - /// Return None if the key is not already in the array or object. - #[doc(hidden)] - fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; - - /// Return None if the key is not already in the array or object. - #[doc(hidden)] - fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; - - /// Panic if array index out of bounds. If key is not already in the object, - /// insert it with a value of null. Panic if Value is a type that cannot be - /// indexed into, except if Value is null then it can be treated as an empty - /// object. - #[doc(hidden)] - fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; -} - -impl Index for usize { - fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { - match *v { - Value::Array(ref 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), - _ => None, - } - } - fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { - match *v { - Value::Array(ref mut vec) => { - let len = vec.len(); - vec.get_mut(*self).unwrap_or_else(|| { - panic!( - "cannot access index {} of JSON array of length {}", - self, len - ) - }) - } - _ => panic!("cannot access index {} of JSON {}", self, Type(v)), - } - } -} - -impl Index for str { - fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { - match *v { - Value::Object(ref 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), - _ => None, - } - } - fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { - 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), - _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), - } - } -} - -impl Index for String { - fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { - self[..].index_into(v) - } - fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { - self[..].index_into_mut(v) - } - fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { - self[..].index_or_insert(v) - } -} - -impl<'a, T> Index for &'a T -where - T: ?Sized + Index, -{ - fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { - (**self).index_into(v) - } - fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { - (**self).index_into_mut(v) - } - fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { - (**self).index_or_insert(v) - } -} - -// Prevent users from implementing the Index trait. -mod private { - pub trait Sealed {} - impl Sealed for usize {} - impl Sealed for str {} - impl Sealed for super::String {} - impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {} -} - -/// Used in panic messages. -struct Type<'a>(&'a Value); - -impl<'a> fmt::Display for Type<'a> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - match *self.0 { - Value::Null => formatter.write_str("null"), - Value::Bool(_) => formatter.write_str("boolean"), - Value::Number(_) => formatter.write_str("number"), - Value::String(_) => formatter.write_str("string"), - Value::Array(_) => formatter.write_str("array"), - Value::Object(_) => formatter.write_str("object"), - } - } -} - -// The usual semantics of Index is to panic on invalid indexing. -// -// That said, the usual semantics are for things like Vec and BTreeMap which -// have different use cases than Value. If you are working with a Vec, you know -// that you are working with a Vec and you can get the len of the Vec and make -// sure your indices are within bounds. The Value use cases are more -// loosey-goosey. You got some JSON from an endpoint and you want to pull values -// out of it. Outside of this Index impl, you already have the option of using -// value.as_array() and working with the Vec directly, or matching on -// Value::Array and getting the Vec directly. The Index impl means you can skip -// that and index directly into the thing using a concise syntax. You don't have -// to check the type, you don't have to check the len, it is all about what you -// expect the Value to look like. -// -// Basically the use cases that would be well served by panicking here are -// better served by using one of the other approaches: get and get_mut, -// as_array, or match. The value of this impl is that it adds a way of working -// with Value that is not well served by the existing approaches: concise and -// careless and sometimes that is exactly what you want. -impl ops::Index for Value -where - I: Index, -{ - type Output = Value; - - /// Index into a `serde_json::Value` using the syntax `value[0]` or - /// `value["k"]`. - /// - /// Returns `Value::Null` if the type of `self` does not match the type of - /// the index, for example if the index is a string and `self` is an array - /// or a number. Also returns `Value::Null` if the given key does not exist - /// in the map or the given index is not within the bounds of the array. - /// - /// For retrieving deeply nested values, you should have a look at the - /// `Value::pointer` method. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// let data = json!({ - /// "x": { - /// "y": ["z", "zz"] - /// } - /// }); - /// - /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); - /// assert_eq!(data["x"]["y"][0], json!("z")); - /// - /// assert_eq!(data["a"], json!(null)); // returns null for undefined values - /// assert_eq!(data["a"]["b"], json!(null)); // does not panic - /// ``` - fn index(&self, index: I) -> &Value { - static NULL: Value = Value::Null; - index.index_into(self).unwrap_or(&NULL) - } -} - -impl ops::IndexMut for Value -where - I: Index, -{ - /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or - /// `value["k"] = ...`. - /// - /// If the index is a number, the value must be an array of length bigger - /// than the index. Indexing into a value that is not an array or an array - /// that is too small will panic. - /// - /// If the index is a string, the value must be an object or null which is - /// treated like an empty object. If the key is not already present in the - /// object, it will be inserted with a value of null. Indexing into a value - /// that is neither an object nor null will panic. - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut data = json!({ "x": 0 }); - /// - /// // replace an existing key - /// data["x"] = json!(1); - /// - /// // insert a new key - /// data["y"] = json!([false, false, false]); - /// - /// // replace an array value - /// data["y"][0] = json!(true); - /// - /// // inserted a deeply nested key - /// data["a"]["b"]["c"]["d"] = json!(true); - /// - /// println!("{}", data); - /// ``` - fn index_mut(&mut self, index: I) -> &mut Value { - index.index_or_insert(self) - } -} diff --git a/json/src/value/mod.rs b/json/src/value/mod.rs deleted file mode 100644 index bb636bf5..00000000 --- a/json/src/value/mod.rs +++ /dev/null @@ -1,1007 +0,0 @@ -//! The Value enum, a loosely typed way of representing any valid JSON value. -//! -//! # Constructing JSON -//! -//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` -//! objects with very natural JSON syntax. -//! -//! ``` -//! use serde_json::json; -//! -//! fn main() { -//! // The type of `john` is `serde_json::Value` -//! let john = json!({ -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }); -//! -//! println!("first phone number: {}", john["phones"][0]); -//! -//! // Convert to a string of JSON and print it out -//! println!("{}", john.to_string()); -//! } -//! ``` -//! -//! 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. -//! -//! ``` -//! # use serde_json::json; -//! # -//! # fn random_phone() -> u16 { 0 } -//! # -//! let full_name = "John Doe"; -//! let age_last_year = 42; -//! -//! // The type of `john` is `serde_json::Value` -//! let john = json!({ -//! "name": full_name, -//! "age": age_last_year + 1, -//! "phones": [ -//! format!("+44 {}", random_phone()) -//! ] -//! }); -//! ``` -//! -//! 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. -//! -//! ``` -//! use serde_json::{json, Value, Error}; -//! -//! fn untyped_example() -> Result<(), Error> { -//! // Some JSON input data as a &str. Maybe this comes from the user. -//! let data = r#" -//! { -//! "name": "John Doe", -//! "age": 43, -//! "phones": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! }"#; -//! -//! // Parse the string of data into serde_json::Value. -//! let v: Value = serde_json::from_str(data)?; -//! -//! // Access parts of the data by indexing with square brackets. -//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); -//! -//! Ok(()) -//! } -//! # -//! # 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 - -use crate::error::Error; -use crate::io; -use crate::lib::*; -use serde::de::DeserializeOwned; -use serde::ser::Serialize; - -pub use self::index::Index; -pub use self::ser::Serializer; -pub use crate::map::Map; -pub use crate::number::Number; - -#[cfg(feature = "raw_value")] -pub use crate::raw::{to_raw_value, RawValue}; - -/// Represents any valid JSON value. -/// -/// See the `serde_json::value` module documentation for usage examples. -#[derive(Clone, Eq, PartialEq)] -pub enum Value { - /// Represents a JSON null value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!(null); - /// ``` - Null, - - /// Represents a JSON boolean. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!(true); - /// ``` - Bool(bool), - - /// Represents a JSON number, whether integer or floating point. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!(12.5); - /// ``` - Number(Number), - - /// Represents a JSON string. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!("a string"); - /// ``` - String(String), - - /// Represents a JSON array. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!(["an", "array"]); - /// ``` - Array(Vec), - - /// Represents a JSON object. - /// - /// By default the map is backed by a BTreeMap. Enable the `preserve_order` - /// feature of serde_json to use IndexMap instead, which preserves - /// entries in the order they are inserted into the map. In particular, this - /// allows JSON data to be deserialized into a Value and serialized to a - /// string while retaining the order of map keys in the input. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "an": "object" }); - /// ``` - Object(Map), -} - -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(")") - } - Value::Object(ref v) => { - formatter.write_str("Object(")?; - Debug::fmt(v, formatter)?; - formatter.write_str(")") - } - } - } -} - -struct WriterFormatter<'a, 'b: 'a> { - inner: &'a mut fmt::Formatter<'b>, -} - -impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { - fn write(&mut self, buf: &[u8]) -> io::Result { - fn io_error(_: E) -> io::Error { - // Error value does not matter because fmt::Display impl below just - // maps it to fmt::Error - io::Error::new(io::ErrorKind::Other, "fmt error") - } - let s = tri!(str::from_utf8(buf).map_err(io_error)); - tri!(self.inner.write_str(s).map_err(io_error)); - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl fmt::Display for Value { - /// Display a JSON value as a string. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let json = json!({ "city": "London", "street": "10 Downing Street" }); - /// - /// // Compact format: - /// // - /// // {"city":"London","street":"10 Downing Street"} - /// let compact = format!("{}", json); - /// assert_eq!(compact, - /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); - /// - /// // Pretty format: - /// // - /// // { - /// // "city": "London", - /// // "street": "10 Downing Street" - /// // } - /// let pretty = format!("{:#}", json); - /// assert_eq!(pretty, - /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); - /// ``` - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let alternate = f.alternate(); - let mut wr = WriterFormatter { inner: f }; - if alternate { - // {:#} - super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) - } else { - // {} - super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) - } - } -} - -fn parse_index(s: &str) -> Option { - if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { - return None; - } - s.parse().ok() -} - -impl Value { - /// Index into a JSON array or map. A string index can be used to access a - /// value in a map, and a usize index can be used to access an element of an - /// array. - /// - /// Returns `None` if the type of `self` does not match the type of the - /// index, for example if the index is a string and `self` is an array or a - /// number. Also returns `None` if the given key does not exist in the map - /// or the given index is not within the bounds of the array. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let object = json!({ "A": 65, "B": 66, "C": 67 }); - /// assert_eq!(*object.get("A").unwrap(), json!(65)); - /// - /// let array = json!([ "A", "B", "C" ]); - /// assert_eq!(*array.get(2).unwrap(), json!("C")); - /// - /// assert_eq!(array.get("A"), None); - /// ``` - /// - /// Square brackets can also be used to index into a value in a more concise - /// way. This returns `Value::Null` in cases where `get` would have returned - /// `None`. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let object = json!({ - /// "A": ["a", "á", "à"], - /// "B": ["b", "b́"], - /// "C": ["c", "ć", "ć̣", "ḉ"], - /// }); - /// assert_eq!(object["B"][0], json!("b")); - /// - /// assert_eq!(object["D"], json!(null)); - /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); - /// ``` - pub fn get(&self, index: I) -> Option<&Value> { - index.index_into(self) - } - - /// Mutably index into a JSON array or map. A string index can be used to - /// access a value in a map, and a usize index can be used to access an - /// element of an array. - /// - /// Returns `None` if the type of `self` does not match the type of the - /// index, for example if the index is a string and `self` is an array or a - /// number. Also returns `None` if the given key does not exist in the map - /// or the given index is not within the bounds of the array. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); - /// *object.get_mut("A").unwrap() = json!(69); - /// - /// let mut array = json!([ "A", "B", "C" ]); - /// *array.get_mut(2).unwrap() = json!("D"); - /// ``` - pub fn get_mut(&mut self, index: I) -> Option<&mut Value> { - index.index_into_mut(self) - } - - /// Returns true if the `Value` is an Object. Returns false otherwise. - /// - /// For any Value on which `is_object` returns true, `as_object` and - /// `as_object_mut` are guaranteed to return the map representation of the - /// object. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); - /// - /// assert!(obj.is_object()); - /// assert!(obj["a"].is_object()); - /// - /// // array, not an object - /// assert!(!obj["b"].is_object()); - /// ``` - pub fn is_object(&self) -> bool { - self.as_object().is_some() - } - - /// If the `Value` is an Object, returns the associated Map. Returns None - /// otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); - /// - /// // The length of `{"nested": true}` is 1 entry. - /// assert_eq!(v["a"].as_object().unwrap().len(), 1); - /// - /// // The array `["an", "array"]` is not an object. - /// assert_eq!(v["b"].as_object(), None); - /// ``` - pub fn as_object(&self) -> Option<&Map> { - match *self { - Value::Object(ref map) => Some(map), - _ => None, - } - } - - /// If the `Value` is an Object, returns the associated mutable Map. - /// Returns None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut v = json!({ "a": { "nested": true } }); - /// - /// v["a"].as_object_mut().unwrap().clear(); - /// assert_eq!(v, json!({ "a": {} })); - /// ``` - pub fn as_object_mut(&mut self) -> Option<&mut Map> { - match *self { - Value::Object(ref mut map) => Some(map), - _ => None, - } - } - - /// Returns true if the `Value` is an Array. Returns false otherwise. - /// - /// For any Value on which `is_array` returns true, `as_array` and - /// `as_array_mut` are guaranteed to return the vector representing the - /// array. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); - /// - /// assert!(obj["a"].is_array()); - /// - /// // an object, not an array - /// assert!(!obj["b"].is_array()); - /// ``` - pub fn is_array(&self) -> bool { - self.as_array().is_some() - } - - /// If the `Value` is an Array, returns the associated vector. Returns None - /// otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); - /// - /// // The length of `["an", "array"]` is 2 elements. - /// assert_eq!(v["a"].as_array().unwrap().len(), 2); - /// - /// // The object `{"an": "object"}` is not an array. - /// assert_eq!(v["b"].as_array(), None); - /// ``` - pub fn as_array(&self) -> Option<&Vec> { - match *self { - Value::Array(ref array) => Some(&*array), - _ => None, - } - } - - /// If the `Value` is an Array, returns the associated mutable vector. - /// Returns None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut v = json!({ "a": ["an", "array"] }); - /// - /// v["a"].as_array_mut().unwrap().clear(); - /// assert_eq!(v, json!({ "a": [] })); - /// ``` - pub fn as_array_mut(&mut self) -> Option<&mut Vec> { - match *self { - Value::Array(ref mut list) => Some(list), - _ => None, - } - } - - /// Returns true if the `Value` is a String. Returns false otherwise. - /// - /// For any Value on which `is_string` returns true, `as_str` is guaranteed - /// to return the string slice. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": "some string", "b": false }); - /// - /// assert!(v["a"].is_string()); - /// - /// // The boolean `false` is not a string. - /// assert!(!v["b"].is_string()); - /// ``` - pub fn is_string(&self) -> bool { - self.as_str().is_some() - } - - /// If the `Value` is a String, returns the associated str. Returns None - /// otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": "some string", "b": false }); - /// - /// assert_eq!(v["a"].as_str(), Some("some string")); - /// - /// // The boolean `false` is not a string. - /// assert_eq!(v["b"].as_str(), None); - /// - /// // JSON values are printed in JSON representation, so strings are in quotes. - /// // - /// // The value is: "some string" - /// println!("The value is: {}", v["a"]); - /// - /// // Rust strings are printed without quotes. - /// // - /// // The value is: some string - /// println!("The value is: {}", v["a"].as_str().unwrap()); - /// ``` - pub fn as_str(&self) -> Option<&str> { - match *self { - Value::String(ref s) => Some(s), - _ => None, - } - } - - /// Returns true if the `Value` is a Number. Returns false otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 1, "b": "2" }); - /// - /// assert!(v["a"].is_number()); - /// - /// // The string `"2"` is a string, not a number. - /// assert!(!v["b"].is_number()); - /// ``` - pub fn is_number(&self) -> bool { - match *self { - Value::Number(_) => true, - _ => false, - } - } - - /// Returns true if the `Value` is an integer between `i64::MIN` and - /// `i64::MAX`. - /// - /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to - /// return the integer value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let big = i64::max_value() as u64 + 10; - /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); - /// - /// assert!(v["a"].is_i64()); - /// - /// // Greater than i64::MAX. - /// assert!(!v["b"].is_i64()); - /// - /// // Numbers with a decimal point are not considered integers. - /// assert!(!v["c"].is_i64()); - /// ``` - pub fn is_i64(&self) -> bool { - match *self { - Value::Number(ref n) => n.is_i64(), - _ => false, - } - } - - /// Returns true if the `Value` is an integer between zero and `u64::MAX`. - /// - /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to - /// return the integer value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); - /// - /// assert!(v["a"].is_u64()); - /// - /// // Negative integer. - /// assert!(!v["b"].is_u64()); - /// - /// // Numbers with a decimal point are not considered integers. - /// assert!(!v["c"].is_u64()); - /// ``` - pub fn is_u64(&self) -> bool { - match *self { - Value::Number(ref n) => n.is_u64(), - _ => false, - } - } - - /// Returns true if the `Value` is a number that can be represented by f64. - /// - /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to - /// return the floating point value. - /// - /// Currently this function returns true if and only if both `is_i64` and - /// `is_u64` return false but this is not a guarantee in the future. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); - /// - /// assert!(v["a"].is_f64()); - /// - /// // Integers. - /// assert!(!v["b"].is_f64()); - /// assert!(!v["c"].is_f64()); - /// ``` - pub fn is_f64(&self) -> bool { - match *self { - Value::Number(ref n) => n.is_f64(), - _ => false, - } - } - - /// If the `Value` is an integer, represent it as i64 if possible. Returns - /// None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let big = i64::max_value() as u64 + 10; - /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); - /// - /// assert_eq!(v["a"].as_i64(), Some(64)); - /// assert_eq!(v["b"].as_i64(), None); - /// assert_eq!(v["c"].as_i64(), None); - /// ``` - pub fn as_i64(&self) -> Option { - match *self { - Value::Number(ref n) => n.as_i64(), - _ => None, - } - } - - /// If the `Value` is an integer, represent it as u64 if possible. Returns - /// None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); - /// - /// assert_eq!(v["a"].as_u64(), Some(64)); - /// assert_eq!(v["b"].as_u64(), None); - /// assert_eq!(v["c"].as_u64(), None); - /// ``` - pub fn as_u64(&self) -> Option { - match *self { - Value::Number(ref n) => n.as_u64(), - _ => None, - } - } - - /// If the `Value` is a number, represent it as f64 if possible. Returns - /// None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); - /// - /// assert_eq!(v["a"].as_f64(), Some(256.0)); - /// assert_eq!(v["b"].as_f64(), Some(64.0)); - /// assert_eq!(v["c"].as_f64(), Some(-64.0)); - /// ``` - pub fn as_f64(&self) -> Option { - match *self { - Value::Number(ref n) => n.as_f64(), - _ => None, - } - } - - /// Returns true if the `Value` is a Boolean. Returns false otherwise. - /// - /// For any Value on which `is_boolean` returns true, `as_bool` is - /// guaranteed to return the boolean value. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": false, "b": "false" }); - /// - /// assert!(v["a"].is_boolean()); - /// - /// // The string `"false"` is a string, not a boolean. - /// assert!(!v["b"].is_boolean()); - /// ``` - pub fn is_boolean(&self) -> bool { - self.as_bool().is_some() - } - - /// If the `Value` is a Boolean, returns the associated bool. Returns None - /// otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": false, "b": "false" }); - /// - /// assert_eq!(v["a"].as_bool(), Some(false)); - /// - /// // The string `"false"` is a string, not a boolean. - /// assert_eq!(v["b"].as_bool(), None); - /// ``` - pub fn as_bool(&self) -> Option { - match *self { - Value::Bool(b) => Some(b), - _ => None, - } - } - - /// Returns true if the `Value` is a Null. Returns false otherwise. - /// - /// For any Value on which `is_null` returns true, `as_null` is guaranteed - /// to return `Some(())`. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": null, "b": false }); - /// - /// assert!(v["a"].is_null()); - /// - /// // The boolean `false` is not null. - /// assert!(!v["b"].is_null()); - /// ``` - pub fn is_null(&self) -> bool { - self.as_null().is_some() - } - - /// If the `Value` is a Null, returns (). Returns None otherwise. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let v = json!({ "a": null, "b": false }); - /// - /// assert_eq!(v["a"].as_null(), Some(())); - /// - /// // The boolean `false` is not null. - /// assert_eq!(v["b"].as_null(), None); - /// ``` - pub fn as_null(&self) -> Option<()> { - match *self { - Value::Null => Some(()), - _ => None, - } - } - - /// Looks up a value by a JSON Pointer. - /// - /// JSON Pointer defines a string syntax for identifying a specific value - /// within a JavaScript Object Notation (JSON) document. - /// - /// A Pointer is a Unicode string with the reference tokens separated by `/`. - /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The - /// addressed value is returned and if there is no such value `None` is - /// returned. - /// - /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). - /// - /// # Examples - /// - /// ``` - /// # use serde_json::json; - /// # - /// let data = json!({ - /// "x": { - /// "y": ["z", "zz"] - /// } - /// }); - /// - /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); - /// assert_eq!(data.pointer("/a/b/c"), None); - /// ``` - pub fn pointer(&self, pointer: &str) -> Option<&Value> { - if pointer == "" { - return Some(self); - } - if !pointer.starts_with('/') { - return None; - } - let tokens = pointer - .split('/') - .skip(1) - .map(|x| x.replace("~1", "/").replace("~0", "~")); - let mut target = self; - - for token in tokens { - let target_opt = match *target { - Value::Object(ref map) => map.get(&token), - Value::Array(ref list) => parse_index(&token).and_then(|x| list.get(x)), - _ => return None, - }; - if let Some(t) = target_opt { - target = t; - } else { - return None; - } - } - Some(target) - } - - /// Looks up a value by a JSON Pointer and returns a mutable reference to - /// that value. - /// - /// JSON Pointer defines a string syntax for identifying a specific value - /// within a JavaScript Object Notation (JSON) document. - /// - /// A Pointer is a Unicode string with the reference tokens separated by `/`. - /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The - /// addressed value is returned and if there is no such value `None` is - /// returned. - /// - /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). - /// - /// # Example of Use - /// - /// ``` - /// use serde_json::Value; - /// - /// fn main() { - /// let s = r#"{"x": 1.0, "y": 2.0}"#; - /// let mut value: Value = serde_json::from_str(s).unwrap(); - /// - /// // Check value using read-only pointer - /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); - /// // Change value with direct assignment - /// *value.pointer_mut("/x").unwrap() = 1.5.into(); - /// // Check that new value was written - /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); - /// // Or change the value only if it exists - /// value.pointer_mut("/x").map(|v| *v = 1.5.into()); - /// - /// // "Steal" ownership of a value. Can replace with any valid Value. - /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); - /// assert_eq!(old_x, 1.5); - /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); - /// } - /// ``` - pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> { - if pointer == "" { - return Some(self); - } - if !pointer.starts_with('/') { - return None; - } - let tokens = pointer - .split('/') - .skip(1) - .map(|x| x.replace("~1", "/").replace("~0", "~")); - let mut target = self; - - for token in tokens { - // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop - // this once-per-loop binding makes the scope clearer and circumvents the error - let target_once = target; - let target_opt = match *target_once { - Value::Object(ref mut map) => map.get_mut(&token), - Value::Array(ref mut list) => { - parse_index(&token).and_then(move |x| list.get_mut(x)) - } - _ => return None, - }; - if let Some(t) = target_opt { - target = t; - } else { - return None; - } - } - Some(target) - } - - /// Takes the value out of the `Value`, leaving a `Null` in its place. - /// - /// ``` - /// # use serde_json::json; - /// # - /// let mut v = json!({ "x": "y" }); - /// assert_eq!(v["x"].take(), json!("y")); - /// assert_eq!(v, json!({ "x": null })); - /// ``` - pub fn take(&mut self) -> Value { - mem::replace(self, Value::Null) - } -} - -/// The default value is `Value::Null`. -/// -/// This is useful for handling omitted `Value` fields when deserializing. -/// -/// # Examples -/// -/// ``` -/// # use serde::Deserialize; -/// use serde_json::Value; -/// -/// #[derive(Deserialize)] -/// struct Settings { -/// level: i32, -/// #[serde(default)] -/// extras: Value, -/// } -/// -/// # fn try_main() -> Result<(), serde_json::Error> { -/// let data = r#" { "level": 42 } "#; -/// let s: Settings = serde_json::from_str(data)?; -/// -/// assert_eq!(s.level, 42); -/// assert_eq!(s.extras, Value::Null); -/// # -/// # Ok(()) -/// # } -/// # -/// # try_main().unwrap() -/// ``` -impl Default for Value { - fn default() -> Value { - Value::Null - } -} - -mod de; -mod from; -mod index; -mod partial_eq; -mod ser; - -/// Convert a `T` into `serde_json::Value` which is an enum that can represent -/// any valid JSON data. -/// -/// # Example -/// -/// ``` -/// use serde::Serialize; -/// use serde_json::json; -/// -/// use std::error::Error; -/// -/// #[derive(Serialize)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn compare_json_values() -> Result<(), Box> { -/// let u = User { -/// fingerprint: "0xF9BA143B95FF6D82".to_owned(), -/// location: "Menlo Park, CA".to_owned(), -/// }; -/// -/// // The type of `expected` is `serde_json::Value` -/// let expected = json!({ -/// "fingerprint": "0xF9BA143B95FF6D82", -/// "location": "Menlo Park, CA", -/// }); -/// -/// let v = serde_json::to_value(u).unwrap(); -/// assert_eq!(v, expected); -/// -/// Ok(()) -/// } -/// # -/// # compare_json_values().unwrap(); -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if `T`'s implementation of `Serialize` decides to -/// fail, or if `T` contains a map with non-string keys. -/// -/// ``` -/// use std::collections::BTreeMap; -/// -/// fn main() { -/// // The keys in this map are vectors, not strings. -/// let mut map = BTreeMap::new(); -/// map.insert(vec![32, 64], "x86"); -/// -/// println!("{}", serde_json::to_value(map).unwrap_err()); -/// } -/// ``` -// Taking by value is more friendly to iterator adapters, option and result -// consumers, etc. See https://github.com/serde-rs/json/pull/149. -pub fn to_value(value: T) -> Result -where - T: Serialize, -{ - value.serialize(Serializer) -} - -/// Interpret a `serde_json::Value` as an instance of type `T`. -/// -/// # Example -/// -/// ``` -/// use serde::Deserialize; -/// use serde_json::json; -/// -/// #[derive(Deserialize, Debug)] -/// struct User { -/// fingerprint: String, -/// location: String, -/// } -/// -/// fn main() { -/// // The type of `j` is `serde_json::Value` -/// let j = json!({ -/// "fingerprint": "0xF9BA143B95FF6D82", -/// "location": "Menlo Park, CA" -/// }); -/// -/// let u: User = serde_json::from_value(j).unwrap(); -/// println!("{:#?}", u); -/// } -/// ``` -/// -/// # Errors -/// -/// This conversion can fail if the structure of the Value does not match the -/// structure expected by `T`, for example if `T` is a struct type but the Value -/// contains something other than a JSON map. It can also fail if the structure -/// is correct but `T`'s implementation of `Deserialize` decides that something -/// is wrong with the data, for example required struct fields are missing from -/// the JSON map or some number is too big to fit in the expected primitive -/// type. -pub fn from_value(value: Value) -> Result -where - T: DeserializeOwned, -{ - T::deserialize(value) -} diff --git a/json/src/value/partial_eq.rs b/json/src/value/partial_eq.rs deleted file mode 100644 index 354ea5a5..00000000 --- a/json/src/value/partial_eq.rs +++ /dev/null @@ -1,95 +0,0 @@ -use super::Value; -use crate::lib::*; - -fn eq_i64(value: &Value, other: i64) -> bool { - value.as_i64().map_or(false, |i| i == other) -} - -fn eq_u64(value: &Value, other: u64) -> bool { - value.as_u64().map_or(false, |i| i == other) -} - -fn eq_f64(value: &Value, other: f64) -> bool { - value.as_f64().map_or(false, |i| i == other) -} - -fn eq_bool(value: &Value, other: bool) -> bool { - value.as_bool().map_or(false, |i| i == other) -} - -fn eq_str(value: &Value, other: &str) -> bool { - value.as_str().map_or(false, |i| i == other) -} - -impl PartialEq for Value { - fn eq(&self, other: &str) -> bool { - eq_str(self, other) - } -} - -impl<'a> PartialEq<&'a str> for Value { - fn eq(&self, other: &&str) -> bool { - eq_str(self, *other) - } -} - -impl PartialEq for str { - fn eq(&self, other: &Value) -> bool { - eq_str(other, self) - } -} - -impl<'a> PartialEq for &'a str { - fn eq(&self, other: &Value) -> bool { - eq_str(other, *self) - } -} - -impl PartialEq for Value { - fn eq(&self, other: &String) -> bool { - eq_str(self, other.as_str()) - } -} - -impl PartialEq for String { - fn eq(&self, other: &Value) -> bool { - eq_str(other, self.as_str()) - } -} - -macro_rules! partialeq_numeric { - ($($eq:ident [$($ty:ty)*])*) => { - $($( - impl PartialEq<$ty> for Value { - fn eq(&self, other: &$ty) -> bool { - $eq(self, *other as _) - } - } - - impl PartialEq for $ty { - fn eq(&self, other: &Value) -> bool { - $eq(other, *self as _) - } - } - - impl<'a> PartialEq<$ty> for &'a Value { - fn eq(&self, other: &$ty) -> bool { - $eq(*self, *other as _) - } - } - - impl<'a> PartialEq<$ty> for &'a mut Value { - fn eq(&self, other: &$ty) -> bool { - $eq(*self, *other as _) - } - } - )*)* - } -} - -partialeq_numeric! { - eq_i64[i8 i16 i32 i64 isize] - eq_u64[u8 u16 u32 u64 usize] - eq_f64[f32 f64] - eq_bool[bool] -} diff --git a/json/src/value/ser.rs b/json/src/value/ser.rs deleted file mode 100644 index 03cb12bb..00000000 --- a/json/src/value/ser.rs +++ /dev/null @@ -1,1019 +0,0 @@ -use crate::error::{Error, ErrorCode, Result}; -use crate::lib::*; -use crate::map::Map; -use crate::number::Number; -use crate::value::{to_value, Value}; -use serde::ser::{Impossible, Serialize}; - -#[cfg(feature = "arbitrary_precision")] -use serde::serde_if_integer128; - -impl Serialize for Value { - #[inline] - fn serialize(&self, serializer: S) -> result::Result - where - S: ::serde::Serializer, - { - 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), - #[cfg(any(feature = "std", feature = "alloc"))] - Value::Object(ref m) => { - use serde::ser::SerializeMap; - let mut map = tri!(serializer.serialize_map(Some(m.len()))); - for (k, v) in m { - tri!(map.serialize_entry(k, v)); - } - map.end() - } - } - } -} - -/// Serializer whose output is a `Value`. -/// -/// This is the serializer that backs [`serde_json::to_value`][crate::to_value]. -/// Unlike the main serde_json serializer which goes from some serializable -/// value of type `T` to JSON text, this one goes from `T` to -/// `serde_json::Value`. -/// -/// The `to_value` function is implementable as: -/// -/// ``` -/// use serde::Serialize; -/// use serde_json::{Error, Value}; -/// -/// pub fn to_value(input: T) -> Result -/// where -/// T: Serialize, -/// { -/// input.serialize(serde_json::value::Serializer) -/// } -/// ``` -pub struct Serializer; - -impl serde::Serializer for Serializer { - type Ok = Value; - type Error = Error; - - type SerializeSeq = SerializeVec; - type SerializeTuple = SerializeVec; - type SerializeTupleStruct = SerializeVec; - type SerializeTupleVariant = SerializeTupleVariant; - type SerializeMap = SerializeMap; - type SerializeStruct = SerializeMap; - type SerializeStructVariant = SerializeStructVariant; - - #[inline] - fn serialize_bool(self, value: bool) -> Result { - Ok(Value::Bool(value)) - } - - #[inline] - fn serialize_i8(self, value: i8) -> Result { - self.serialize_i64(value as i64) - } - - #[inline] - fn serialize_i16(self, value: i16) -> Result { - self.serialize_i64(value as i64) - } - - #[inline] - fn serialize_i32(self, value: i32) -> Result { - self.serialize_i64(value as i64) - } - - fn serialize_i64(self, value: i64) -> Result { - Ok(Value::Number(value.into())) - } - - #[cfg(feature = "arbitrary_precision")] - serde_if_integer128! { - fn serialize_i128(self, value: i128) -> Result { - Ok(Value::Number(value.into())) - } - } - - #[inline] - fn serialize_u8(self, value: u8) -> Result { - self.serialize_u64(value as u64) - } - - #[inline] - fn serialize_u16(self, value: u16) -> Result { - self.serialize_u64(value as u64) - } - - #[inline] - fn serialize_u32(self, value: u32) -> Result { - self.serialize_u64(value as u64) - } - - #[inline] - fn serialize_u64(self, value: u64) -> Result { - Ok(Value::Number(value.into())) - } - - #[cfg(feature = "arbitrary_precision")] - serde_if_integer128! { - fn serialize_u128(self, value: u128) -> Result { - Ok(Value::Number(value.into())) - } - } - - #[inline] - fn serialize_f32(self, value: f32) -> Result { - self.serialize_f64(value as f64) - } - - #[inline] - fn serialize_f64(self, value: f64) -> Result { - Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) - } - - #[inline] - fn serialize_char(self, value: char) -> Result { - let mut s = String::new(); - s.push(value); - Ok(Value::String(s)) - } - - #[inline] - fn serialize_str(self, value: &str) -> Result { - Ok(Value::String(value.to_owned())) - } - - fn serialize_bytes(self, value: &[u8]) -> Result { - let vec = value.iter().map(|&b| Value::Number(b.into())).collect(); - Ok(Value::Array(vec)) - } - - #[inline] - fn serialize_unit(self) -> Result { - Ok(Value::Null) - } - - #[inline] - fn serialize_unit_struct(self, _name: &'static str) -> Result { - self.serialize_unit() - } - - #[inline] - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - ) -> Result { - self.serialize_str(variant) - } - - #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - let mut values = Map::new(); - values.insert(String::from(variant), tri!(to_value(&value))); - Ok(Value::Object(values)) - } - - #[inline] - fn serialize_none(self) -> Result { - self.serialize_unit() - } - - #[inline] - fn serialize_some(self, value: &T) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - fn serialize_seq(self, len: Option) -> Result { - Ok(SerializeVec { - vec: Vec::with_capacity(len.unwrap_or(0)), - }) - } - - fn serialize_tuple(self, len: usize) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - len: usize, - ) -> Result { - self.serialize_seq(Some(len)) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - len: usize, - ) -> Result { - Ok(SerializeTupleVariant { - name: String::from(variant), - vec: Vec::with_capacity(len), - }) - } - - fn serialize_map(self, _len: Option) -> Result { - Ok(SerializeMap::Map { - map: Map::new(), - next_key: None, - }) - } - - fn serialize_struct(self, name: &'static str, len: usize) -> Result { - match name { - #[cfg(feature = "arbitrary_precision")] - crate::number::TOKEN => Ok(SerializeMap::Number { out_value: None }), - #[cfg(feature = "raw_value")] - crate::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }), - _ => self.serialize_map(Some(len)), - } - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - _len: usize, - ) -> Result { - Ok(SerializeStructVariant { - name: String::from(variant), - map: Map::new(), - }) - } - - fn collect_str(self, value: &T) -> Result - where - T: Display, - { - Ok(Value::String(value.to_string())) - } -} - -pub struct SerializeVec { - vec: Vec, -} - -pub struct SerializeTupleVariant { - name: String, - vec: Vec, -} - -pub enum SerializeMap { - Map { - map: Map, - next_key: Option, - }, - #[cfg(feature = "arbitrary_precision")] - Number { out_value: Option }, - #[cfg(feature = "raw_value")] - RawValue { out_value: Option }, -} - -pub struct SerializeStructVariant { - name: String, - map: Map, -} - -impl serde::ser::SerializeSeq for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_element(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - self.vec.push(tri!(to_value(&value))); - Ok(()) - } - - fn end(self) -> Result { - Ok(Value::Array(self.vec)) - } -} - -impl serde::ser::SerializeTuple for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_element(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - serde::ser::SerializeSeq::serialize_element(self, value) - } - - fn end(self) -> Result { - serde::ser::SerializeSeq::end(self) - } -} - -impl serde::ser::SerializeTupleStruct for SerializeVec { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - serde::ser::SerializeSeq::serialize_element(self, value) - } - - fn end(self) -> Result { - serde::ser::SerializeSeq::end(self) - } -} - -impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - self.vec.push(tri!(to_value(&value))); - Ok(()) - } - - fn end(self) -> Result { - let mut object = Map::new(); - - object.insert(self.name, Value::Array(self.vec)); - - Ok(Value::Object(object)) - } -} - -impl serde::ser::SerializeMap for SerializeMap { - type Ok = Value; - type Error = Error; - - fn serialize_key(&mut self, key: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - SerializeMap::Map { - ref mut next_key, .. - } => { - *next_key = Some(tri!(key.serialize(MapKeySerializer))); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - SerializeMap::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - SerializeMap::RawValue { .. } => unreachable!(), - } - } - - fn serialize_value(&mut self, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - SerializeMap::Map { - ref mut map, - ref mut 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))); - Ok(()) - } - #[cfg(feature = "arbitrary_precision")] - SerializeMap::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - SerializeMap::RawValue { .. } => unreachable!(), - } - } - - fn end(self) -> Result { - match self { - SerializeMap::Map { map, .. } => Ok(Value::Object(map)), - #[cfg(feature = "arbitrary_precision")] - SerializeMap::Number { .. } => unreachable!(), - #[cfg(feature = "raw_value")] - SerializeMap::RawValue { .. } => unreachable!(), - } - } -} - -struct MapKeySerializer; - -fn key_must_be_a_string() -> Error { - Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) -} - -impl serde::Serializer for MapKeySerializer { - type Ok = String; - type Error = Error; - - type SerializeSeq = Impossible; - type SerializeTuple = Impossible; - type SerializeTupleStruct = Impossible; - type SerializeTupleVariant = Impossible; - type SerializeMap = Impossible; - type SerializeStruct = Impossible; - type SerializeStructVariant = Impossible; - - #[inline] - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - variant: &'static str, - ) -> Result { - Ok(variant.to_owned()) - } - - #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result - where - T: ?Sized + Serialize, - { - value.serialize(self) - } - - fn serialize_bool(self, _value: bool) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_i8(self, value: i8) -> Result { - Ok(value.to_string()) - } - - fn serialize_i16(self, value: i16) -> Result { - Ok(value.to_string()) - } - - fn serialize_i32(self, value: i32) -> Result { - Ok(value.to_string()) - } - - fn serialize_i64(self, value: i64) -> Result { - Ok(value.to_string()) - } - - fn serialize_u8(self, value: u8) -> Result { - Ok(value.to_string()) - } - - fn serialize_u16(self, value: u16) -> Result { - Ok(value.to_string()) - } - - fn serialize_u32(self, value: u32) -> Result { - Ok(value.to_string()) - } - - fn serialize_u64(self, value: u64) -> Result { - Ok(value.to_string()) - } - - fn serialize_f32(self, _value: f32) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_f64(self, _value: f64) -> Result { - Err(key_must_be_a_string()) - } - - #[inline] - fn serialize_char(self, value: char) -> Result { - Ok({ - let mut s = String::new(); - s.push(value); - s - }) - } - - #[inline] - fn serialize_str(self, value: &str) -> Result { - Ok(value.to_owned()) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_unit(self) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - Err(key_must_be_a_string()) - } - - fn serialize_none(self) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_some(self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - Err(key_must_be_a_string()) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(key_must_be_a_string()) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(key_must_be_a_string()) - } - - fn collect_str(self, value: &T) -> Result - where - T: Display, - { - Ok(value.to_string()) - } -} - -impl serde::ser::SerializeStruct for SerializeMap { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - match *self { - SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value), - #[cfg(feature = "arbitrary_precision")] - SerializeMap::Number { ref mut out_value } => { - if key == crate::number::TOKEN { - *out_value = Some(value.serialize(NumberValueEmitter)?); - Ok(()) - } else { - Err(invalid_number()) - } - } - #[cfg(feature = "raw_value")] - SerializeMap::RawValue { ref mut out_value } => { - if key == crate::raw::TOKEN { - *out_value = Some(value.serialize(RawValueEmitter)?); - Ok(()) - } else { - Err(invalid_raw_value()) - } - } - } - } - - fn end(self) -> Result { - match self { - SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), - #[cfg(feature = "arbitrary_precision")] - SerializeMap::Number { out_value, .. } => { - Ok(out_value.expect("number value was not emitted")) - } - #[cfg(feature = "raw_value")] - SerializeMap::RawValue { out_value, .. } => { - Ok(out_value.expect("raw value was not emitted")) - } - } - } -} - -impl serde::ser::SerializeStructVariant for SerializeStructVariant { - type Ok = Value; - type Error = Error; - - fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> - where - T: ?Sized + Serialize, - { - self.map.insert(String::from(key), tri!(to_value(&value))); - Ok(()) - } - - fn end(self) -> Result { - let mut object = Map::new(); - - object.insert(self.name, Value::Object(self.map)); - - Ok(Value::Object(object)) - } -} - -#[cfg(feature = "arbitrary_precision")] -struct NumberValueEmitter; - -#[cfg(feature = "arbitrary_precision")] -fn invalid_number() -> Error { - Error::syntax(ErrorCode::InvalidNumber, 0, 0) -} - -#[cfg(feature = "arbitrary_precision")] -impl serde::ser::Serializer for NumberValueEmitter { - type Ok = Value; - type Error = Error; - - type SerializeSeq = Impossible; - type SerializeTuple = Impossible; - type SerializeTupleStruct = Impossible; - type SerializeTupleVariant = Impossible; - type SerializeMap = Impossible; - type SerializeStruct = Impossible; - type SerializeStructVariant = Impossible; - - fn serialize_bool(self, _v: bool) -> Result { - Err(invalid_number()) - } - - fn serialize_i8(self, _v: i8) -> Result { - Err(invalid_number()) - } - - fn serialize_i16(self, _v: i16) -> Result { - Err(invalid_number()) - } - - fn serialize_i32(self, _v: i32) -> Result { - Err(invalid_number()) - } - - fn serialize_i64(self, _v: i64) -> Result { - Err(invalid_number()) - } - - fn serialize_u8(self, _v: u8) -> Result { - Err(invalid_number()) - } - - fn serialize_u16(self, _v: u16) -> Result { - Err(invalid_number()) - } - - fn serialize_u32(self, _v: u32) -> Result { - Err(invalid_number()) - } - - fn serialize_u64(self, _v: u64) -> Result { - Err(invalid_number()) - } - - fn serialize_f32(self, _v: f32) -> Result { - Err(invalid_number()) - } - - fn serialize_f64(self, _v: f64) -> Result { - Err(invalid_number()) - } - - fn serialize_char(self, _v: char) -> Result { - Err(invalid_number()) - } - - fn serialize_str(self, value: &str) -> Result { - let n = tri!(value.to_owned().parse()); - Ok(Value::Number(n)) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result { - Err(invalid_number()) - } - - fn serialize_none(self) -> Result { - Err(invalid_number()) - } - - fn serialize_some(self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_unit(self) -> Result { - Err(invalid_number()) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result { - Err(invalid_number()) - } - - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> Result { - Err(invalid_number()) - } - - fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_number()) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(invalid_number()) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(invalid_number()) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_number()) - } -} - -#[cfg(feature = "raw_value")] -struct RawValueEmitter; - -#[cfg(feature = "raw_value")] -fn invalid_raw_value() -> Error { - Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) -} - -#[cfg(feature = "raw_value")] -impl serde::ser::Serializer for RawValueEmitter { - type Ok = Value; - type Error = Error; - - type SerializeSeq = Impossible; - type SerializeTuple = Impossible; - type SerializeTupleStruct = Impossible; - type SerializeTupleVariant = Impossible; - type SerializeMap = Impossible; - type SerializeStruct = Impossible; - type SerializeStructVariant = Impossible; - - fn serialize_bool(self, _v: bool) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_i8(self, _v: i8) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_i16(self, _v: i16) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_i32(self, _v: i32) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_i64(self, _v: i64) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_u8(self, _v: u8) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_u16(self, _v: u16) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_u32(self, _v: u32) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_u64(self, _v: u64) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_f32(self, _v: f32) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_f64(self, _v: f64) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_char(self, _v: char) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_str(self, value: &str) -> Result { - crate::from_str(value) - } - - fn serialize_bytes(self, _value: &[u8]) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_none(self) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_some(self, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_raw_value()) - } - - fn serialize_unit(self) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_unit_struct(self, _name: &'static str) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_unit_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - ) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_raw_value()) - } - - fn serialize_newtype_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _value: &T, - ) -> Result - where - T: ?Sized + Serialize, - { - Err(invalid_raw_value()) - } - - fn serialize_seq(self, _len: Option) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_tuple(self, _len: usize) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - ) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_tuple_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_map(self, _len: Option) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { - Err(invalid_raw_value()) - } - - fn serialize_struct_variant( - self, - _name: &'static str, - _variant_index: u32, - _variant: &'static str, - _len: usize, - ) -> Result { - Err(invalid_raw_value()) - } -} diff --git a/json/tests/compiletest.rs b/json/tests/compiletest.rs deleted file mode 100644 index f9aea23b..00000000 --- a/json/tests/compiletest.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[rustversion::attr(not(nightly), ignore)] -#[test] -fn ui() { - let t = trybuild::TestCases::new(); - t.compile_fail("tests/ui/*.rs"); -} diff --git a/json/tests/crate/Cargo.toml b/json/tests/crate/Cargo.toml deleted file mode 100644 index 59da7c72..00000000 --- a/json/tests/crate/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "serde_json_test" -version = "0.0.0" -edition = "2018" -publish = false - -[lib] -path = "test.rs" - -[dependencies] -serde_json = { path = "../..", default-features = false } - -[features] -default = ["std"] -std = ["serde_json/std"] -alloc = ["serde_json/alloc"] -preserve_order = ["serde_json/preserve_order"] -arbitrary_precision = ["serde_json/arbitrary_precision"] -raw_value = ["serde_json/raw_value"] -unbounded_depth = ["serde_json/unbounded_depth"] diff --git a/json/tests/crate/test.rs b/json/tests/crate/test.rs deleted file mode 100644 index 3661f864..00000000 --- a/json/tests/crate/test.rs +++ /dev/null @@ -1 +0,0 @@ -pub use serde_json::*; diff --git a/json/tests/debug.rs b/json/tests/debug.rs deleted file mode 100644 index d2d8448b..00000000 --- a/json/tests/debug.rs +++ /dev/null @@ -1,68 +0,0 @@ -use serde_json::{json, Number, Value}; - -#[test] -fn number() { - assert_eq!(format!("{:?}", Number::from(1)), "Number(1)"); - assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)"); - assert_eq!( - format!("{:?}", Number::from_f64(1.0).unwrap()), - "Number(1.0)" - ); -} - -#[test] -fn value_null() { - assert_eq!(format!("{:?}", json!(null)), "Null"); -} - -#[test] -fn value_bool() { - assert_eq!(format!("{:?}", json!(true)), "Bool(true)"); - assert_eq!(format!("{:?}", json!(false)), "Bool(false)"); -} - -#[test] -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)"); -} - -#[test] -fn value_string() { - assert_eq!(format!("{:?}", json!("s")), "String(\"s\")"); -} - -#[test] -fn value_array() { - assert_eq!(format!("{:?}", json!([])), "Array([])"); -} - -#[test] -fn value_object() { - assert_eq!(format!("{:?}", json!({})), "Object({})"); -} - -#[test] -fn error() { - let err = serde_json::from_str::("{0}").unwrap_err(); - let expected = "Error(\"key must be a string\", line: 1, column: 2)"; - 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); -} diff --git a/json/tests/macros/mod.rs b/json/tests/macros/mod.rs deleted file mode 100644 index 2c11ce96..00000000 --- a/json/tests/macros/mod.rs +++ /dev/null @@ -1,59 +0,0 @@ -macro_rules! json_str { - ([]) => { - "[]" - }; - ([ $e1:tt $(, $e:tt)* ]) => { - concat!("[", - json_str!($e1), - $(",", json_str!($e),)* - "]") - }; - ({}) => { - "{}" - }; - ({ $k1:tt : $v1:tt $(, $k:tt : $v:tt)* }) => { - concat!("{", - stringify!($k1), ":", json_str!($v1), - $(",", stringify!($k), ":", json_str!($v),)* - "}") - }; - (($other:tt)) => { - $other - }; - ($other:tt) => { - stringify!($other) - }; -} - -macro_rules! pretty_str { - ($json:tt) => { - pretty_str_impl!("", $json) - }; -} - -macro_rules! pretty_str_impl { - ($indent:expr, []) => { - "[]" - }; - ($indent:expr, [ $e1:tt $(, $e:tt)* ]) => { - concat!("[\n ", - $indent, pretty_str_impl!(concat!(" ", $indent), $e1), - $(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)* - "\n", $indent, "]") - }; - ($indent:expr, {}) => { - "{}" - }; - ($indent:expr, { $k1:tt : $v1:tt $(, $k:tt : $v:tt)* }) => { - concat!("{\n ", - $indent, stringify!($k1), ": ", pretty_str_impl!(concat!(" ", $indent), $v1), - $(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)* - "\n", $indent, "}") - }; - ($indent:expr, ($other:tt)) => { - $other - }; - ($indent:expr, $other:tt) => { - stringify!($other) - }; -} diff --git a/json/tests/map.rs b/json/tests/map.rs deleted file mode 100644 index 387a72cd..00000000 --- a/json/tests/map.rs +++ /dev/null @@ -1,36 +0,0 @@ -use serde_json::{from_str, Map, Value}; - -#[test] -fn test_preserve_order() { - // Sorted order - #[cfg(not(feature = "preserve_order"))] - const EXPECTED: &[&str] = &["a", "b", "c"]; - - // Insertion order - #[cfg(feature = "preserve_order")] - const EXPECTED: &[&str] = &["b", "a", "c"]; - - let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); - let keys: Vec<_> = v.as_object().unwrap().keys().collect(); - assert_eq!(keys, EXPECTED); -} - -#[test] -fn test_append() { - // Sorted order - #[cfg(not(feature = "preserve_order"))] - const EXPECTED: &[&str] = &["a", "b", "c"]; - - // Insertion order - #[cfg(feature = "preserve_order")] - const EXPECTED: &[&str] = &["b", "a", "c"]; - - let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); - let val = v.as_object_mut().unwrap(); - let mut m = Map::new(); - m.append(val); - let keys: Vec<_> = m.keys().collect(); - - assert_eq!(keys, EXPECTED); - assert!(val.is_empty()); -} diff --git a/json/tests/regression.rs b/json/tests/regression.rs deleted file mode 100644 index 34c67d20..00000000 --- a/json/tests/regression.rs +++ /dev/null @@ -1,2 +0,0 @@ -#[path = "regression/mod.rs"] -mod regression; diff --git a/json/tests/regression/issue520.rs b/json/tests/regression/issue520.rs deleted file mode 100644 index 6befd494..00000000 --- a/json/tests/regression/issue520.rs +++ /dev/null @@ -1,18 +0,0 @@ -use serde_derive::{Serialize, Deserialize}; - -#[derive(Serialize, Deserialize, Debug)] -#[serde(tag = "type", content = "data")] -enum E { - Float(f32), -} - -#[test] -fn test() { - let e = E::Float(159.1); - let v = serde_json::to_value(e).unwrap(); - let e = serde_json::from_value::(v).unwrap(); - - match e { - E::Float(f) => assert_eq!(f, 159.1), - } -} diff --git a/json/tests/regression/mod.rs b/json/tests/regression/mod.rs deleted file mode 100644 index 830175fc..00000000 --- a/json/tests/regression/mod.rs +++ /dev/null @@ -1 +0,0 @@ -automod::dir!("tests/regression"); diff --git a/json/tests/stream.rs b/json/tests/stream.rs deleted file mode 100644 index ca54e9a1..00000000 --- a/json/tests/stream.rs +++ /dev/null @@ -1,182 +0,0 @@ -#![cfg(not(feature = "preserve_order"))] - -use serde_json::{json, Deserializer, Value}; - -// Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740 -#[rustfmt::skip] -macro_rules! test_stream { - ($data:expr, $ty:ty, |$stream:ident| $test:block) => { - { - let de = Deserializer::from_str($data); - let mut $stream = de.into_iter::<$ty>(); - assert_eq!($stream.byte_offset(), 0); - $test - } - { - let de = Deserializer::from_slice($data.as_bytes()); - let mut $stream = de.into_iter::<$ty>(); - assert_eq!($stream.byte_offset(), 0); - $test - } - { - let mut bytes = $data.as_bytes(); - let de = Deserializer::from_reader(&mut bytes); - let mut $stream = de.into_iter::<$ty>(); - assert_eq!($stream.byte_offset(), 0); - $test - } - }; -} - -#[test] -fn test_json_stream_newlines() { - let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}"; - - test_stream!(data, Value, |stream| { - assert_eq!(stream.next().unwrap().unwrap()["x"], 39); - assert_eq!(stream.byte_offset(), 8); - - assert_eq!(stream.next().unwrap().unwrap()["x"], 40); - assert_eq!(stream.byte_offset(), 17); - - assert_eq!(stream.next().unwrap().unwrap()["x"], 41); - assert_eq!(stream.byte_offset(), 25); - - assert_eq!(stream.next().unwrap().unwrap()["x"], 42); - assert_eq!(stream.byte_offset(), 34); - - assert!(stream.next().is_none()); - assert_eq!(stream.byte_offset(), 34); - }); -} - -#[test] -fn test_json_stream_trailing_whitespaces() { - let data = "{\"x\":42} \t\n"; - - test_stream!(data, Value, |stream| { - assert_eq!(stream.next().unwrap().unwrap()["x"], 42); - assert_eq!(stream.byte_offset(), 8); - - assert!(stream.next().is_none()); - assert_eq!(stream.byte_offset(), 11); - }); -} - -#[test] -fn test_json_stream_truncated() { - let data = "{\"x\":40}\n{\"x\":"; - - test_stream!(data, Value, |stream| { - assert_eq!(stream.next().unwrap().unwrap()["x"], 40); - assert_eq!(stream.byte_offset(), 8); - - assert!(stream.next().unwrap().unwrap_err().is_eof()); - assert_eq!(stream.byte_offset(), 9); - }); -} - -#[test] -fn test_json_stream_truncated_decimal() { - let data = "{\"x\":4."; - - test_stream!(data, Value, |stream| { - assert!(stream.next().unwrap().unwrap_err().is_eof()); - assert_eq!(stream.byte_offset(), 0); - }); -} - -#[test] -fn test_json_stream_truncated_negative() { - let data = "{\"x\":-"; - - test_stream!(data, Value, |stream| { - assert!(stream.next().unwrap().unwrap_err().is_eof()); - assert_eq!(stream.byte_offset(), 0); - }); -} - -#[test] -fn test_json_stream_truncated_exponent() { - let data = "{\"x\":4e"; - - test_stream!(data, Value, |stream| { - assert!(stream.next().unwrap().unwrap_err().is_eof()); - assert_eq!(stream.byte_offset(), 0); - }); -} - -#[test] -fn test_json_stream_empty() { - let data = ""; - - test_stream!(data, Value, |stream| { - assert!(stream.next().is_none()); - assert_eq!(stream.byte_offset(), 0); - }); -} - -#[test] -fn test_json_stream_primitive() { - let data = "{} true{}1[]\nfalse\"hey\"2 "; - - test_stream!(data, Value, |stream| { - assert_eq!(stream.next().unwrap().unwrap(), json!({})); - assert_eq!(stream.byte_offset(), 2); - - assert_eq!(stream.next().unwrap().unwrap(), true); - assert_eq!(stream.byte_offset(), 7); - - assert_eq!(stream.next().unwrap().unwrap(), json!({})); - assert_eq!(stream.byte_offset(), 9); - - assert_eq!(stream.next().unwrap().unwrap(), 1); - assert_eq!(stream.byte_offset(), 10); - - assert_eq!(stream.next().unwrap().unwrap(), json!([])); - assert_eq!(stream.byte_offset(), 12); - - assert_eq!(stream.next().unwrap().unwrap(), false); - assert_eq!(stream.byte_offset(), 18); - - assert_eq!(stream.next().unwrap().unwrap(), "hey"); - assert_eq!(stream.byte_offset(), 23); - - assert_eq!(stream.next().unwrap().unwrap(), 2); - assert_eq!(stream.byte_offset(), 24); - - assert!(stream.next().is_none()); - assert_eq!(stream.byte_offset(), 25); - }); -} - -#[test] -fn test_json_stream_invalid_literal() { - let data = "truefalse"; - - test_stream!(data, Value, |stream| { - let second = stream.next().unwrap().unwrap_err(); - assert_eq!(second.to_string(), "trailing characters at line 1 column 5"); - }); -} - -#[test] -fn test_json_stream_invalid_number() { - let data = "1true"; - - test_stream!(data, Value, |stream| { - let second = stream.next().unwrap().unwrap_err(); - assert_eq!(second.to_string(), "trailing characters at line 1 column 2"); - }); -} - -#[test] -fn test_error() { - let data = "true wrong false"; - - test_stream!(data, Value, |stream| { - assert_eq!(stream.next().unwrap().unwrap(), true); - assert!(stream.next().unwrap().is_err()); - assert!(stream.next().is_none()); - }); -} diff --git a/json/tests/test.rs b/json/tests/test.rs deleted file mode 100644 index a47093b2..00000000 --- a/json/tests/test.rs +++ /dev/null @@ -1,2196 +0,0 @@ -#![cfg(not(feature = "preserve_order"))] -#![allow(clippy::float_cmp, clippy::unreadable_literal)] -#![cfg_attr(feature = "trace-macros", feature(trace_macros))] -#[cfg(feature = "trace-macros")] -trace_macros!(true); - -#[macro_use] -mod macros; - -use serde::de::{self, IgnoredAny, IntoDeserializer}; -use serde::ser::{self, Serializer}; -use serde::{Deserialize, Serialize}; -use serde_bytes::{ByteBuf, Bytes}; -use serde_json::{ - from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value, - to_vec, to_writer, Deserializer, Number, Value, -}; -use std::collections::BTreeMap; -use std::fmt::{self, Debug}; -use std::io; -use std::iter; -use std::marker::PhantomData; -use std::str::FromStr; -use std::string::ToString; -use std::{f32, f64}; -use std::{i16, i32, i64, i8}; -use std::{u16, u32, u64, u8}; - -macro_rules! treemap { - () => { - BTreeMap::new() - }; - ($($k:expr => $v:expr),+) => { - { - let mut m = BTreeMap::new(); - $( - m.insert($k, $v); - )+ - m - } - }; -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(deny_unknown_fields)] -enum Animal { - Dog, - Frog(String, Vec), - Cat { age: usize, name: String }, - AntHive(Vec), -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -struct Inner { - a: (), - b: usize, - c: Vec, -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -struct Outer { - inner: Vec, -} - -fn test_encode_ok(errors: &[(T, &str)]) -where - T: PartialEq + Debug + ser::Serialize, -{ - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = to_string(value).unwrap(); - assert_eq!(s, out); - - let v = to_value(&value).unwrap(); - let s = to_string(&v).unwrap(); - assert_eq!(s, out); - } -} - -fn test_pretty_encode_ok(errors: &[(T, &str)]) -where - T: PartialEq + Debug + ser::Serialize, -{ - for &(ref value, out) in errors { - let out = out.to_string(); - - let s = to_string_pretty(value).unwrap(); - assert_eq!(s, out); - - let v = to_value(&value).unwrap(); - let s = to_string_pretty(&v).unwrap(); - assert_eq!(s, out); - } -} - -#[test] -fn test_write_null() { - let tests = &[((), "null")]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_u64() { - let tests = &[(3u64, "3"), (u64::MAX, &u64::MAX.to_string())]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_i64() { - let tests = &[ - (3i64, "3"), - (-2i64, "-2"), - (-1234i64, "-1234"), - (i64::MIN, &i64::MIN.to_string()), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_f64() { - let tests = &[ - (3.0, "3.0"), - (3.1, "3.1"), - (-1.5, "-1.5"), - (0.5, "0.5"), - (f64::MIN, "-1.7976931348623157e308"), - (f64::MAX, "1.7976931348623157e308"), - (f64::EPSILON, "2.220446049250313e-16"), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_encode_nonfinite_float_yields_null() { - let v = to_value(::std::f64::NAN).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f64::INFINITY).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f32::NAN).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f32::INFINITY).unwrap(); - assert!(v.is_null()); -} - -#[test] -fn test_write_str() { - let tests = &[("", "\"\""), ("foo", "\"foo\"")]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_bool() { - let tests = &[(true, "true"), (false, "false")]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_char() { - let tests = &[ - ('n', "\"n\""), - ('"', "\"\\\"\""), - ('\\', "\"\\\\\""), - ('/', "\"/\""), - ('\x08', "\"\\b\""), - ('\x0C', "\"\\f\""), - ('\n', "\"\\n\""), - ('\r', "\"\\r\""), - ('\t', "\"\\t\""), - ('\x0B', "\"\\u000b\""), - ('\u{3A3}', "\"\u{3A3}\""), - ]; - test_encode_ok(tests); - test_pretty_encode_ok(tests); -} - -#[test] -fn test_write_list() { - test_encode_ok(&[ - (vec![], "[]"), - (vec![true], "[true]"), - (vec![true, false], "[true,false]"), - ]); - - test_encode_ok(&[ - (vec![vec![], vec![], vec![]], "[[],[],[]]"), - (vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"), - (vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"), - (vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"), - ]); - - test_pretty_encode_ok(&[ - (vec![vec![], vec![], vec![]], pretty_str!([[], [], []])), - ( - vec![vec![1, 2, 3], vec![], vec![]], - pretty_str!([[1, 2, 3], [], []]), - ), - ( - vec![vec![], vec![1, 2, 3], vec![]], - pretty_str!([[], [1, 2, 3], []]), - ), - ( - vec![vec![], vec![], vec![1, 2, 3]], - pretty_str!([[], [], [1, 2, 3]]), - ), - ]); - - test_pretty_encode_ok(&[ - (vec![], "[]"), - (vec![true], pretty_str!([true])), - (vec![true, false], pretty_str!([true, false])), - ]); - - let long_test_list = json!([false, null, ["foo\nbar", 3.5]]); - - test_encode_ok(&[( - long_test_list.clone(), - json_str!([false, null, ["foo\nbar", 3.5]]), - )]); - - test_pretty_encode_ok(&[( - long_test_list, - pretty_str!([false, null, ["foo\nbar", 3.5]]), - )]); -} - -#[test] -fn test_write_object() { - test_encode_ok(&[ - (treemap!(), "{}"), - (treemap!("a".to_string() => true), "{\"a\":true}"), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - "{\"a\":true,\"b\":false}", - ), - ]); - - test_encode_ok(&[ - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "{\"a\":{},\"b\":{},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "c".to_string() => treemap![] - ], - "{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}", - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ] - ], - "{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}", - ), - ]); - - test_encode_ok(&[(treemap!['c' => ()], "{\"c\":null}")]); - - test_pretty_encode_ok(&[ - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - pretty_str!({ - "a": {}, - "b": {}, - "c": {} - }), - ), - ( - treemap![ - "a".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - pretty_str!({ - "a": { - "a": { - "a": [ - 1, - 2, - 3 - ] - }, - "b": {}, - "c": {} - }, - "b": {}, - "c": {} - }), - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ], - "c".to_string() => treemap![] - ], - pretty_str!({ - "a": {}, - "b": { - "a": { - "a": [ - 1, - 2, - 3 - ] - }, - "b": {}, - "c": {} - }, - "c": {} - }), - ), - ( - treemap![ - "a".to_string() => treemap![], - "b".to_string() => treemap![], - "c".to_string() => treemap![ - "a".to_string() => treemap!["a" => vec![1,2,3]], - "b".to_string() => treemap![], - "c".to_string() => treemap![] - ] - ], - pretty_str!({ - "a": {}, - "b": {}, - "c": { - "a": { - "a": [ - 1, - 2, - 3 - ] - }, - "b": {}, - "c": {} - } - }), - ), - ]); - - test_pretty_encode_ok(&[ - (treemap!(), "{}"), - ( - treemap!("a".to_string() => true), - pretty_str!({ - "a": true - }), - ), - ( - treemap!( - "a".to_string() => true, - "b".to_string() => false - ), - pretty_str!( { - "a": true, - "b": false - }), - ), - ]); - - let complex_obj = json!({ - "b": [ - {"c": "\x0c\x1f\r"}, - {"d": ""} - ] - }); - - test_encode_ok(&[( - complex_obj.clone(), - json_str!({ - "b": [ - { - "c": (r#""\f\u001f\r""#) - }, - { - "d": "" - } - ] - }), - )]); - - test_pretty_encode_ok(&[( - complex_obj.clone(), - pretty_str!({ - "b": [ - { - "c": (r#""\f\u001f\r""#) - }, - { - "d": "" - } - ] - }), - )]); -} - -#[test] -fn test_write_tuple() { - test_encode_ok(&[((5,), "[5]")]); - - test_pretty_encode_ok(&[((5,), pretty_str!([5]))]); - - test_encode_ok(&[((5, (6, "abc")), "[5,[6,\"abc\"]]")]); - - test_pretty_encode_ok(&[((5, (6, "abc")), pretty_str!([5, [6, "abc"]]))]); -} - -#[test] -fn test_write_enum() { - test_encode_ok(&[ - (Animal::Dog, "\"Dog\""), - ( - Animal::Frog("Henry".to_string(), vec![]), - "{\"Frog\":[\"Henry\",[]]}", - ), - ( - Animal::Frog("Henry".to_string(), vec![349]), - "{\"Frog\":[\"Henry\",[349]]}", - ), - ( - Animal::Frog("Henry".to_string(), vec![349, 102]), - "{\"Frog\":[\"Henry\",[349,102]]}", - ), - ( - Animal::Cat { - age: 5, - name: "Kate".to_string(), - }, - "{\"Cat\":{\"age\":5,\"name\":\"Kate\"}}", - ), - ( - Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]), - "{\"AntHive\":[\"Bob\",\"Stuart\"]}", - ), - ]); - - test_pretty_encode_ok(&[ - (Animal::Dog, "\"Dog\""), - ( - Animal::Frog("Henry".to_string(), vec![]), - pretty_str!({ - "Frog": [ - "Henry", - [] - ] - }), - ), - ( - Animal::Frog("Henry".to_string(), vec![349]), - pretty_str!({ - "Frog": [ - "Henry", - [ - 349 - ] - ] - }), - ), - ( - Animal::Frog("Henry".to_string(), vec![349, 102]), - pretty_str!({ - "Frog": [ - "Henry", - [ - 349, - 102 - ] - ] - }), - ), - ]); -} - -#[test] -fn test_write_option() { - test_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]); - - test_encode_ok(&[ - (None, "null"), - (Some(vec!["foo", "bar"]), "[\"foo\",\"bar\"]"), - ]); - - test_pretty_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]); - - test_pretty_encode_ok(&[ - (None, "null"), - (Some(vec!["foo", "bar"]), pretty_str!(["foo", "bar"])), - ]); -} - -#[test] -fn test_write_newtype_struct() { - #[derive(Serialize, PartialEq, Debug)] - struct Newtype(BTreeMap); - - let inner = Newtype(treemap!(String::from("inner") => 123)); - let outer = treemap!(String::from("outer") => to_value(&inner).unwrap()); - - test_encode_ok(&[(inner, r#"{"inner":123}"#)]); - - test_encode_ok(&[(outer, r#"{"outer":{"inner":123}}"#)]); -} - -#[test] -fn test_deserialize_number_to_untagged_enum() { - #[derive(Eq, PartialEq, Deserialize, Debug)] - #[serde(untagged)] - enum E { - N(i64), - } - - assert_eq!(E::N(0), E::deserialize(Number::from(0)).unwrap()); -} - -fn test_parse_ok(tests: Vec<(&str, T)>) -where - T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned, -{ - for (s, value) in tests { - let v: T = from_str(s).unwrap(); - assert_eq!(v, value.clone()); - - let v: T = from_slice(s.as_bytes()).unwrap(); - assert_eq!(v, value.clone()); - - // Make sure we can deserialize into a `Value`. - let json_value: Value = from_str(s).unwrap(); - assert_eq!(json_value, to_value(&value).unwrap()); - - // Make sure we can deserialize from a `&Value`. - let v = T::deserialize(&json_value).unwrap(); - assert_eq!(v, value); - - // Make sure we can deserialize from a `Value`. - let v: T = from_value(json_value.clone()).unwrap(); - assert_eq!(v, value); - - // Make sure we can round trip back to `Value`. - let json_value2: Value = from_value(json_value.clone()).unwrap(); - assert_eq!(json_value2, json_value); - - // Make sure we can fully ignore. - let twoline = s.to_owned() + "\n3735928559"; - let mut de = Deserializer::from_str(&twoline); - IgnoredAny::deserialize(&mut de).unwrap(); - assert_eq!(0xDEAD_BEEF, u64::deserialize(&mut de).unwrap()); - - // Make sure every prefix is an EOF error, except that a prefix of a - // number may be a valid number. - if !json_value.is_number() { - for (i, _) in s.trim_end().char_indices() { - assert!(from_str::(&s[..i]).unwrap_err().is_eof()); - assert!(from_str::(&s[..i]).unwrap_err().is_eof()); - } - } - } -} - -// For testing representations that the deserializer accepts but the serializer -// never generates. These do not survive a round-trip through Value. -fn test_parse_unusual_ok(tests: Vec<(&str, T)>) -where - T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned, -{ - for (s, value) in tests { - let v: T = from_str(s).unwrap(); - assert_eq!(v, value.clone()); - - let v: T = from_slice(s.as_bytes()).unwrap(); - assert_eq!(v, value.clone()); - } -} - -macro_rules! test_parse_err { - ($name:ident::<$($ty:ty),*>($arg:expr) => $expected:expr) => { - let actual = $name::<$($ty),*>($arg).unwrap_err().to_string(); - assert_eq!(actual, $expected, "unexpected {} error", stringify!($name)); - }; -} - -fn test_parse_err(errors: &[(&str, &'static str)]) -where - T: Debug + PartialEq + de::DeserializeOwned, -{ - for &(s, err) in errors { - test_parse_err!(from_str::(s) => err); - test_parse_err!(from_slice::(s.as_bytes()) => err); - } -} - -fn test_parse_slice_err(errors: &[(&[u8], &'static str)]) -where - T: Debug + PartialEq + de::DeserializeOwned, -{ - for &(s, err) in errors { - test_parse_err!(from_slice::(s) => err); - } -} - -fn test_fromstr_parse_err(errors: &[(&str, &'static str)]) -where - T: Debug + PartialEq + FromStr, - ::Err: ToString, -{ - for &(s, err) in errors { - let actual = s.parse::().unwrap_err().to_string(); - assert_eq!(actual, err, "unexpected parsing error"); - } -} - -#[test] -fn test_parse_null() { - test_parse_err::<()>(&[ - ("n", "EOF while parsing a value at line 1 column 1"), - ("nul", "EOF while parsing a value at line 1 column 3"), - ("nulla", "trailing characters at line 1 column 5"), - ]); - - test_parse_ok(vec![("null", ())]); -} - -#[test] -fn test_parse_bool() { - test_parse_err::(&[ - ("t", "EOF while parsing a value at line 1 column 1"), - ("truz", "expected ident at line 1 column 4"), - ("f", "EOF while parsing a value at line 1 column 1"), - ("faz", "expected ident at line 1 column 3"), - ("truea", "trailing characters at line 1 column 5"), - ("falsea", "trailing characters at line 1 column 6"), - ]); - - test_parse_ok(vec![ - ("true", true), - (" true ", true), - ("false", false), - (" false ", false), - ]); -} - -#[test] -fn test_parse_char() { - test_parse_err::(&[ - ( - "\"ab\"", - "invalid value: string \"ab\", expected a character at line 1 column 4", - ), - ( - "10", - if cfg!(feature = "arbitrary_precision") { - "invalid type: number, expected a character at line 1 column 2" - } else { - "invalid type: integer `10`, expected a character at line 1 column 2" - }, - ), - ]); - - test_parse_ok(vec![ - ("\"n\"", 'n'), - ("\"\\\"\"", '"'), - ("\"\\\\\"", '\\'), - ("\"/\"", '/'), - ("\"\\b\"", '\x08'), - ("\"\\f\"", '\x0C'), - ("\"\\n\"", '\n'), - ("\"\\r\"", '\r'), - ("\"\\t\"", '\t'), - ("\"\\u000b\"", '\x0B'), - ("\"\\u000B\"", '\x0B'), - ("\"\u{3A3}\"", '\u{3A3}'), - ]); -} - -#[test] -fn test_parse_number_errors() { - test_parse_err::(&[ - ("+", "expected value at line 1 column 1"), - (".", "expected value at line 1 column 1"), - ("-", "EOF while parsing a value at line 1 column 1"), - ("00", "invalid number at line 1 column 2"), - ("0x80", "trailing characters at line 1 column 2"), - ("\\0", "expected value at line 1 column 1"), - ("1.", "EOF while parsing a value at line 1 column 2"), - ("1.a", "invalid number at line 1 column 3"), - ("1.e1", "invalid number at line 1 column 3"), - ("1e", "EOF while parsing a value at line 1 column 2"), - ("1e+", "EOF while parsing a value at line 1 column 3"), - ("1a", "trailing characters at line 1 column 2"), - ( - "100e777777777777777777777777777", - "number out of range at line 1 column 14", - ), - ( - "-100e777777777777777777777777777", - "number out of range at line 1 column 15", - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000", // 1e309 - "number out of range at line 1 column 310", - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - .0e9", // 1e309 - "number out of range at line 1 column 305", - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - e9", // 1e309 - "number out of range at line 1 column 303", - ), - ]); -} - -#[test] -fn test_parse_i64() { - test_parse_ok(vec![ - ("-2", -2), - ("-1234", -1234), - (" -1234 ", -1234), - (&i64::MIN.to_string(), i64::MIN), - (&i64::MAX.to_string(), i64::MAX), - ]); -} - -#[test] -fn test_parse_u64() { - test_parse_ok(vec![ - ("0", 0u64), - ("3", 3u64), - ("1234", 1234), - (&u64::MAX.to_string(), u64::MAX), - ]); -} - -#[test] -fn test_parse_negative_zero() { - for negative_zero in &[ - "-0.0", - "-0e2", - "-0.0e2", - "-1e-400", - "-1e-4000000000000000000000000000000000000000000000000", - ] { - assert!( - from_str::(negative_zero).unwrap().is_sign_negative(), - "should have been negative: {:?}", - negative_zero - ); - } -} - -#[test] -fn test_parse_f64() { - test_parse_ok(vec![ - ("0.0", 0.0f64), - ("3.0", 3.0f64), - ("3.1", 3.1), - ("-1.2", -1.2), - ("0.4", 0.4), - ]); - - #[cfg(not(feature = "arbitrary_precision"))] - test_parse_ok(vec![ - // With arbitrary-precision enabled, this parses as Number{"3.00"} - // but the float is Number{"3.0"} - ("3.00", 3.0f64), - ("0.4e5", 0.4e5), - ("0.4e+5", 0.4e5), - ("0.4e15", 0.4e15), - ("0.4e+15", 0.4e15), - ("0.4e-01", 0.4e-1), - (" 0.4e-01 ", 0.4e-1), - ("0.4e-001", 0.4e-1), - ("0.4e-0", 0.4e0), - ("0.00e00", 0.0), - ("0.00e+00", 0.0), - ("0.00e-00", 0.0), - ("3.5E-2147483647", 0.0), - ( - &format!("{}", (i64::MIN as f64) - 1.0), - (i64::MIN as f64) - 1.0, - ), - ( - &format!("{}", (u64::MAX as f64) + 1.0), - (u64::MAX as f64) + 1.0, - ), - (&format!("{}", f64::EPSILON), f64::EPSILON), - ( - "0.0000000000000000000000000000000000000000000000000123e50", - 1.23, - ), - ("100e-777777777777777777777777777", 0.0), - ( - "1010101010101010101010101010101010101010", - 10101010101010101010e20, - ), - ( - "0.1010101010101010101010101010101010101010", - 0.1010101010101010101, - ), - ("0e1000000000000000000000000000000000000000000000", 0.0), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 00000000", - 1e308, - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - .0e8", - 1e308, - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - e8", - 1e308, - ), - ( - "1000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000000000000000000000000000000000000000000000\ - 000000000000000000e-10", - 1e308, - ), - ("5e-324", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005), - ("31.245270191439438", 31.245270191439438), - ("-31.245270191439438", -31.245270191439438), - ("121.48791951161945", 121.48791951161945), - ("-121.48791951161945", -121.48791951161945), - ("100.78399658203125", 100.78399658203125), - ("-100.78399658203125", -100.78399658203125), - ]); -} - -#[test] -fn test_serialize_char() { - let value = json!( - ({ - let mut map = BTreeMap::new(); - map.insert('c', ()); - map - }) - ); - assert_eq!(&Value::Null, value.get("c").unwrap()); -} - -#[cfg(feature = "arbitrary_precision")] -#[test] -fn test_malicious_number() { - #[derive(Serialize)] - #[serde(rename = "$serde_json::private::Number")] - struct S { - #[serde(rename = "$serde_json::private::Number")] - f: &'static str, - } - - let actual = serde_json::to_value(&S { f: "not a number" }) - .unwrap_err() - .to_string(); - assert_eq!(actual, "invalid number at line 1 column 1"); -} - -#[test] -fn test_parse_number() { - test_parse_ok(vec![ - ("0.0", Number::from_f64(0.0f64).unwrap()), - ("3.0", Number::from_f64(3.0f64).unwrap()), - ("3.1", Number::from_f64(3.1).unwrap()), - ("-1.2", Number::from_f64(-1.2).unwrap()), - ("0.4", Number::from_f64(0.4).unwrap()), - ]); - - test_fromstr_parse_err::(&[ - (" 1.0", "invalid number at line 1 column 1"), - ("1.0 ", "invalid number at line 1 column 4"), - ("\t1.0", "invalid number at line 1 column 1"), - ("1.0\t", "invalid number at line 1 column 4"), - ]); - - #[cfg(feature = "arbitrary_precision")] - test_parse_ok(vec![ - ("1e999", Number::from_string_unchecked("1e999".to_owned())), - ("-1e999", Number::from_string_unchecked("-1e999".to_owned())), - ("1e-999", Number::from_string_unchecked("1e-999".to_owned())), - ( - "2.3e999", - Number::from_string_unchecked("2.3e999".to_owned()), - ), - ( - "-2.3e999", - Number::from_string_unchecked("-2.3e999".to_owned()), - ), - ]); -} - -#[test] -fn test_parse_string() { - test_parse_err::(&[ - ("\"", "EOF while parsing a string at line 1 column 1"), - ("\"lol", "EOF while parsing a string at line 1 column 4"), - ("\"lol\"a", "trailing characters at line 1 column 6"), - ( - "\"\\uD83C\\uFFFF\"", - "lone leading surrogate in hex escape at line 1 column 13", - ), - ( - "\"\n\"", - "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0", - ), - ( - "\"\x1F\"", - "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2", - ), - ]); - - test_parse_slice_err::(&[ - ( - &[b'"', 159, 146, 150, b'"'], - "invalid unicode code point at line 1 column 5", - ), - ( - &[b'"', b'\\', b'n', 159, 146, 150, b'"'], - "invalid unicode code point at line 1 column 7", - ), - ( - &[b'"', b'\\', b'u', 48, 48, 51], - "EOF while parsing a string at line 1 column 6", - ), - ( - &[b'"', b'\\', b'u', 250, 48, 51, 48, b'"'], - "invalid escape at line 1 column 4", - ), - ( - &[b'"', b'\\', b'u', 48, 250, 51, 48, b'"'], - "invalid escape at line 1 column 5", - ), - ( - &[b'"', b'\\', b'u', 48, 48, 250, 48, b'"'], - "invalid escape at line 1 column 6", - ), - ( - &[b'"', b'\\', b'u', 48, 48, 51, 250, b'"'], - "invalid escape at line 1 column 7", - ), - ( - &[b'"', b'\n', b'"'], - "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0", - ), - ( - &[b'"', b'\x1F', b'"'], - "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2", - ), - ]); - - test_parse_ok(vec![ - ("\"\"", "".to_string()), - ("\"foo\"", "foo".to_string()), - (" \"foo\" ", "foo".to_string()), - ("\"\\\"\"", "\"".to_string()), - ("\"\\b\"", "\x08".to_string()), - ("\"\\n\"", "\n".to_string()), - ("\"\\r\"", "\r".to_string()), - ("\"\\t\"", "\t".to_string()), - ("\"\\u12ab\"", "\u{12ab}".to_string()), - ("\"\\uAB12\"", "\u{AB12}".to_string()), - ("\"\\uD83C\\uDF95\"", "\u{1F395}".to_string()), - ]); -} - -#[test] -fn test_parse_list() { - test_parse_err::>(&[ - ("[", "EOF while parsing a list at line 1 column 1"), - ("[ ", "EOF while parsing a list at line 1 column 2"), - ("[1", "EOF while parsing a list at line 1 column 2"), - ("[1,", "EOF while parsing a value at line 1 column 3"), - ("[1,]", "trailing comma at line 1 column 4"), - ("[1 2]", "expected `,` or `]` at line 1 column 4"), - ("[]a", "trailing characters at line 1 column 3"), - ]); - - test_parse_ok(vec![ - ("[]", vec![]), - ("[ ]", vec![]), - ("[null]", vec![()]), - (" [ null ] ", vec![()]), - ]); - - test_parse_ok(vec![("[true]", vec![true])]); - - test_parse_ok(vec![("[3,1]", vec![3u64, 1]), (" [ 3 , 1 ] ", vec![3, 1])]); - - test_parse_ok(vec![("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]])]); - - test_parse_ok(vec![("[1]", (1u64,))]); - - test_parse_ok(vec![("[1, 2]", (1u64, 2u64))]); - - test_parse_ok(vec![("[1, 2, 3]", (1u64, 2u64, 3u64))]); - - test_parse_ok(vec![("[1, [2, 3]]", (1u64, (2u64, 3u64)))]); -} - -#[test] -fn test_parse_object() { - test_parse_err::>(&[ - ("{", "EOF while parsing an object at line 1 column 1"), - ("{ ", "EOF while parsing an object at line 1 column 2"), - ("{1", "key must be a string at line 1 column 2"), - ("{ \"a\"", "EOF while parsing an object at line 1 column 5"), - ("{\"a\"", "EOF while parsing an object at line 1 column 4"), - ("{\"a\" ", "EOF while parsing an object at line 1 column 5"), - ("{\"a\" 1", "expected `:` at line 1 column 6"), - ("{\"a\":", "EOF while parsing a value at line 1 column 5"), - ("{\"a\":1", "EOF while parsing an object at line 1 column 6"), - ("{\"a\":1 1", "expected `,` or `}` at line 1 column 8"), - ("{\"a\":1,", "EOF while parsing a value at line 1 column 7"), - ("{}a", "trailing characters at line 1 column 3"), - ]); - - test_parse_ok(vec![ - ("{}", treemap!()), - ("{ }", treemap!()), - ("{\"a\":3}", treemap!("a".to_string() => 3u64)), - ("{ \"a\" : 3 }", treemap!("a".to_string() => 3)), - ( - "{\"a\":3,\"b\":4}", - treemap!("a".to_string() => 3, "b".to_string() => 4), - ), - ( - " { \"a\" : 3 , \"b\" : 4 } ", - treemap!("a".to_string() => 3, "b".to_string() => 4), - ), - ]); - - test_parse_ok(vec![( - "{\"a\": {\"b\": 3, \"c\": 4}}", - treemap!( - "a".to_string() => treemap!( - "b".to_string() => 3u64, - "c".to_string() => 4 - ) - ), - )]); - - test_parse_ok(vec![("{\"c\":null}", treemap!('c' => ()))]); -} - -#[test] -fn test_parse_struct() { - test_parse_err::(&[ - ( - "5", - if cfg!(feature = "arbitrary_precision") { - "invalid type: number, expected struct Outer at line 1 column 1" - } else { - "invalid type: integer `5`, expected struct Outer at line 1 column 1" - }, - ), - ( - "\"hello\"", - "invalid type: string \"hello\", expected struct Outer at line 1 column 7", - ), - ( - "{\"inner\": true}", - "invalid type: boolean `true`, expected a sequence at line 1 column 14", - ), - ("{}", "missing field `inner` at line 1 column 2"), - ( - r#"{"inner": [{"b": 42, "c": []}]}"#, - "missing field `a` at line 1 column 29", - ), - ]); - - test_parse_ok(vec![ - ( - "{ - \"inner\": [] - }", - Outer { inner: vec![] }, - ), - ( - "{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }", - Outer { - inner: vec![Inner { - a: (), - b: 2, - c: vec!["abc".to_string(), "xyz".to_string()], - }], - }, - ), - ]); - - let v: Outer = from_str( - "[ - [ - [ null, 2, [\"abc\", \"xyz\"] ] - ] - ]", - ) - .unwrap(); - - assert_eq!( - v, - Outer { - inner: vec![Inner { - a: (), - b: 2, - c: vec!["abc".to_string(), "xyz".to_string()], - }], - } - ); - - let j = json!([null, 2, []]); - Inner::deserialize(&j).unwrap(); - Inner::deserialize(j).unwrap(); -} - -#[test] -fn test_parse_option() { - test_parse_ok(vec![ - ("null", None::), - ("\"jodhpurs\"", Some("jodhpurs".to_string())), - ]); - - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] - struct Foo { - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - test_parse_ok(vec![ - ("{\"x\": null}", Foo { x: None }), - ("{\"x\": 5}", Foo { x: Some(5) }), - ]); -} - -#[test] -fn test_parse_enum_errors() { - test_parse_err::( - &[ - ("{}", "expected value at line 1 column 2"), - ("[]", "expected value at line 1 column 1"), - ("\"unknown\"", - "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 9"), - ("{\"unknown\":null}", - "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 10"), - ("{\"Dog\":", "EOF while parsing a value at line 1 column 7"), - ("{\"Dog\":}", "expected value at line 1 column 8"), - ("{\"Dog\":{}}", "invalid type: map, expected unit at line 1 column 7"), - ("\"Frog\"", "invalid type: unit variant, expected tuple variant"), - ("\"Frog\" 0 ", "invalid type: unit variant, expected tuple variant"), - ("{\"Frog\":{}}", - "invalid type: map, expected tuple variant Animal::Frog at line 1 column 8"), - ("{\"Cat\":[]}", "invalid length 0, expected struct variant Animal::Cat with 2 elements at line 1 column 9"), - ("{\"Cat\":[0]}", "invalid length 1, expected struct variant Animal::Cat with 2 elements at line 1 column 10"), - ("{\"Cat\":[0, \"\", 2]}", "trailing characters at line 1 column 16"), - ("{\"Cat\":{\"age\": 5, \"name\": \"Kate\", \"foo\":\"bar\"}", - "unknown field `foo`, expected `age` or `name` at line 1 column 39"), - - // JSON does not allow trailing commas in data structures - ("{\"Cat\":[0, \"Kate\",]}", "trailing comma at line 1 column 19"), - ("{\"Cat\":{\"age\": 2, \"name\": \"Kate\",}}", - "trailing comma at line 1 column 34"), - ], - ); -} - -#[test] -fn test_parse_enum() { - test_parse_ok(vec![ - ("\"Dog\"", Animal::Dog), - (" \"Dog\" ", Animal::Dog), - ( - "{\"Frog\":[\"Henry\",[]]}", - Animal::Frog("Henry".to_string(), vec![]), - ), - ( - " { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ", - Animal::Frog("Henry".to_string(), vec![349, 102]), - ), - ( - "{\"Cat\": {\"age\": 5, \"name\": \"Kate\"}}", - Animal::Cat { - age: 5, - name: "Kate".to_string(), - }, - ), - ( - " { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ", - Animal::Cat { - age: 5, - name: "Kate".to_string(), - }, - ), - ( - " { \"AntHive\" : [\"Bob\", \"Stuart\"] } ", - Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]), - ), - ]); - - test_parse_unusual_ok(vec![ - ("{\"Dog\":null}", Animal::Dog), - (" { \"Dog\" : null } ", Animal::Dog), - ]); - - test_parse_ok(vec![( - concat!( - "{", - " \"a\": \"Dog\",", - " \"b\": {\"Frog\":[\"Henry\", []]}", - "}" - ), - treemap!( - "a".to_string() => Animal::Dog, - "b".to_string() => Animal::Frog("Henry".to_string(), vec![]) - ), - )]); -} - -#[test] -fn test_parse_trailing_whitespace() { - test_parse_ok(vec![ - ("[1, 2] ", vec![1u64, 2]), - ("[1, 2]\n", vec![1, 2]), - ("[1, 2]\t", vec![1, 2]), - ("[1, 2]\t \n", vec![1, 2]), - ]); -} - -#[test] -fn test_multiline_errors() { - test_parse_err::>(&[( - "{\n \"foo\":\n \"bar\"", - "EOF while parsing an object at line 3 column 6", - )]); -} - -#[test] -fn test_missing_option_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{\"x\": 5}").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); - - let value: Foo = from_value(json!({})).unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_value(json!({"x": 5})).unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_missing_nonoption_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - x: u32, - } - - test_parse_err::(&[("{}", "missing field `x` at line 1 column 2")]); -} - -#[test] -fn test_missing_renamed_field() { - #[derive(Debug, PartialEq, Deserialize)] - struct Foo { - #[serde(rename = "y")] - x: Option, - } - - let value: Foo = from_str("{}").unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_str("{\"y\": 5}").unwrap(); - assert_eq!(value, Foo { x: Some(5) }); - - let value: Foo = from_value(json!({})).unwrap(); - assert_eq!(value, Foo { x: None }); - - let value: Foo = from_value(json!({"y": 5})).unwrap(); - assert_eq!(value, Foo { x: Some(5) }); -} - -#[test] -fn test_serialize_seq_with_no_len() { - #[derive(Clone, Debug, PartialEq)] - struct MyVec(Vec); - - impl ser::Serialize for MyVec - where - T: ser::Serialize, - { - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: ser::Serializer, - { - use serde::ser::SerializeSeq; - let mut seq = serializer.serialize_seq(None)?; - for elem in &self.0 { - seq.serialize_element(elem)?; - } - seq.end() - } - } - - struct Visitor { - marker: PhantomData>, - } - - impl<'de, T> de::Visitor<'de> for Visitor - where - T: de::Deserialize<'de>, - { - type Value = MyVec; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("array") - } - - #[inline] - fn visit_unit(self) -> Result, E> - where - E: de::Error, - { - Ok(MyVec(Vec::new())) - } - - #[inline] - fn visit_seq(self, mut visitor: V) -> Result, V::Error> - where - V: de::SeqAccess<'de>, - { - let mut values = Vec::new(); - - while let Some(value) = visitor.next_element()? { - values.push(value); - } - - Ok(MyVec(values)) - } - } - - impl<'de, T> de::Deserialize<'de> for MyVec - where - T: de::Deserialize<'de>, - { - fn deserialize(deserializer: D) -> Result, D::Error> - where - D: de::Deserializer<'de>, - { - deserializer.deserialize_map(Visitor { - marker: PhantomData, - }) - } - } - - let mut vec = Vec::new(); - vec.push(MyVec(Vec::new())); - vec.push(MyVec(Vec::new())); - let vec: MyVec> = MyVec(vec); - - test_encode_ok(&[(vec.clone(), "[[],[]]")]); - - let s = to_string_pretty(&vec).unwrap(); - let expected = pretty_str!([[], []]); - assert_eq!(s, expected); -} - -#[test] -fn test_serialize_map_with_no_len() { - #[derive(Clone, Debug, PartialEq)] - struct MyMap(BTreeMap); - - impl ser::Serialize for MyMap - where - K: ser::Serialize + Ord, - V: ser::Serialize, - { - #[inline] - fn serialize(&self, serializer: S) -> Result - where - S: ser::Serializer, - { - use serde::ser::SerializeMap; - let mut map = serializer.serialize_map(None)?; - for (k, v) in &self.0 { - map.serialize_entry(k, v)?; - } - map.end() - } - } - - struct Visitor { - marker: PhantomData>, - } - - impl<'de, K, V> de::Visitor<'de> for Visitor - where - K: de::Deserialize<'de> + Eq + Ord, - V: de::Deserialize<'de>, - { - type Value = MyMap; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("map") - } - - #[inline] - fn visit_unit(self) -> Result, E> - where - E: de::Error, - { - Ok(MyMap(BTreeMap::new())) - } - - #[inline] - fn visit_map(self, mut visitor: Visitor) -> Result, Visitor::Error> - where - Visitor: de::MapAccess<'de>, - { - let mut values = BTreeMap::new(); - - while let Some((key, value)) = visitor.next_entry()? { - values.insert(key, value); - } - - Ok(MyMap(values)) - } - } - - impl<'de, K, V> de::Deserialize<'de> for MyMap - where - K: de::Deserialize<'de> + Eq + Ord, - V: de::Deserialize<'de>, - { - fn deserialize(deserializer: D) -> Result, D::Error> - where - D: de::Deserializer<'de>, - { - deserializer.deserialize_map(Visitor { - marker: PhantomData, - }) - } - } - - let mut map = BTreeMap::new(); - map.insert("a", MyMap(BTreeMap::new())); - map.insert("b", MyMap(BTreeMap::new())); - let map: MyMap<_, MyMap> = MyMap(map); - - test_encode_ok(&[(map.clone(), "{\"a\":{},\"b\":{}}")]); - - let s = to_string_pretty(&map).unwrap(); - let expected = pretty_str!({ - "a": {}, - "b": {} - }); - assert_eq!(s, expected); -} - -#[test] -fn test_deserialize_from_stream() { - use serde::Deserialize; - use std::net; - use std::thread; - - #[derive(Debug, PartialEq, Serialize, Deserialize)] - struct Message { - message: String, - } - - let l = net::TcpListener::bind("localhost:20000").unwrap(); - - thread::spawn(|| { - let l = l; - for stream in l.incoming() { - let mut stream = stream.unwrap(); - let read_stream = stream.try_clone().unwrap(); - - let mut de = Deserializer::from_reader(read_stream); - let request = Message::deserialize(&mut de).unwrap(); - let response = Message { - message: request.message, - }; - to_writer(&mut stream, &response).unwrap(); - } - }); - - let mut stream = net::TcpStream::connect("localhost:20000").unwrap(); - let request = Message { - message: "hi there".to_string(), - }; - to_writer(&mut stream, &request).unwrap(); - - let mut de = Deserializer::from_reader(stream); - let response = Message::deserialize(&mut de).unwrap(); - - assert_eq!(request, response); -} - -#[test] -fn test_serialize_rejects_bool_keys() { - let map = treemap!( - true => 2, - false => 4 - ); - - let err = to_vec(&map).unwrap_err(); - assert_eq!(err.to_string(), "key must be a string"); -} - -#[test] -fn test_serialize_rejects_adt_keys() { - let map = treemap!( - Some("a") => 2, - Some("b") => 4, - None => 6 - ); - - let err = to_vec(&map).unwrap_err(); - assert_eq!(err.to_string(), "key must be a string"); -} - -#[test] -fn test_bytes_ser() { - let buf = vec![]; - let bytes = Bytes::new(&buf); - assert_eq!(to_string(&bytes).unwrap(), "[]".to_string()); - - let buf = vec![1, 2, 3]; - let bytes = Bytes::new(&buf); - assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_string()); -} - -#[test] -fn test_byte_buf_ser() { - let bytes = ByteBuf::new(); - assert_eq!(to_string(&bytes).unwrap(), "[]".to_string()); - - let bytes = ByteBuf::from(vec![1, 2, 3]); - assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_string()); -} - -#[test] -fn test_byte_buf_de() { - let bytes = ByteBuf::new(); - let v: ByteBuf = from_str("[]").unwrap(); - assert_eq!(v, bytes); - - let bytes = ByteBuf::from(vec![1, 2, 3]); - let v: ByteBuf = from_str("[1, 2, 3]").unwrap(); - assert_eq!(v, bytes); -} - -#[test] -fn test_byte_buf_de_multiple() { - let s: Vec = from_str(r#"["ab\nc", "cd\ne"]"#).unwrap(); - let a = ByteBuf::from(b"ab\nc".to_vec()); - let b = ByteBuf::from(b"cd\ne".to_vec()); - assert_eq!(vec![a, b], s); -} - -#[test] -fn test_json_pointer() { - // Test case taken from https://tools.ietf.org/html/rfc6901#page-5 - let data: Value = from_str( - r#"{ - "foo": ["bar", "baz"], - "": 0, - "a/b": 1, - "c%d": 2, - "e^f": 3, - "g|h": 4, - "i\\j": 5, - "k\"l": 6, - " ": 7, - "m~n": 8 - }"#, - ) - .unwrap(); - assert_eq!(data.pointer("").unwrap(), &data); - assert_eq!(data.pointer("/foo").unwrap(), &json!(["bar", "baz"])); - assert_eq!(data.pointer("/foo/0").unwrap(), &json!("bar")); - assert_eq!(data.pointer("/").unwrap(), &json!(0)); - assert_eq!(data.pointer("/a~1b").unwrap(), &json!(1)); - assert_eq!(data.pointer("/c%d").unwrap(), &json!(2)); - assert_eq!(data.pointer("/e^f").unwrap(), &json!(3)); - assert_eq!(data.pointer("/g|h").unwrap(), &json!(4)); - assert_eq!(data.pointer("/i\\j").unwrap(), &json!(5)); - assert_eq!(data.pointer("/k\"l").unwrap(), &json!(6)); - assert_eq!(data.pointer("/ ").unwrap(), &json!(7)); - assert_eq!(data.pointer("/m~0n").unwrap(), &json!(8)); - // Invalid pointers - assert!(data.pointer("/unknown").is_none()); - assert!(data.pointer("/e^f/ertz").is_none()); - assert!(data.pointer("/foo/00").is_none()); - assert!(data.pointer("/foo/01").is_none()); -} - -#[test] -fn test_json_pointer_mut() { - use std::mem; - - // Test case taken from https://tools.ietf.org/html/rfc6901#page-5 - let mut data: Value = from_str( - r#"{ - "foo": ["bar", "baz"], - "": 0, - "a/b": 1, - "c%d": 2, - "e^f": 3, - "g|h": 4, - "i\\j": 5, - "k\"l": 6, - " ": 7, - "m~n": 8 - }"#, - ) - .unwrap(); - - // Basic pointer checks - assert_eq!(data.pointer_mut("/foo").unwrap(), &json!(["bar", "baz"])); - assert_eq!(data.pointer_mut("/foo/0").unwrap(), &json!("bar")); - assert_eq!(data.pointer_mut("/").unwrap(), 0); - assert_eq!(data.pointer_mut("/a~1b").unwrap(), 1); - assert_eq!(data.pointer_mut("/c%d").unwrap(), 2); - assert_eq!(data.pointer_mut("/e^f").unwrap(), 3); - assert_eq!(data.pointer_mut("/g|h").unwrap(), 4); - assert_eq!(data.pointer_mut("/i\\j").unwrap(), 5); - assert_eq!(data.pointer_mut("/k\"l").unwrap(), 6); - assert_eq!(data.pointer_mut("/ ").unwrap(), 7); - assert_eq!(data.pointer_mut("/m~0n").unwrap(), 8); - - // Invalid pointers - assert!(data.pointer_mut("/unknown").is_none()); - assert!(data.pointer_mut("/e^f/ertz").is_none()); - assert!(data.pointer_mut("/foo/00").is_none()); - assert!(data.pointer_mut("/foo/01").is_none()); - - // Mutable pointer checks - *data.pointer_mut("/").unwrap() = 100.into(); - assert_eq!(data.pointer("/").unwrap(), 100); - *data.pointer_mut("/foo/0").unwrap() = json!("buzz"); - assert_eq!(data.pointer("/foo/0").unwrap(), &json!("buzz")); - - // Example of ownership stealing - assert_eq!( - data.pointer_mut("/a~1b") - .map(|m| mem::replace(m, json!(null))) - .unwrap(), - 1 - ); - assert_eq!(data.pointer("/a~1b").unwrap(), &json!(null)); - - // Need to compare against a clone so we don't anger the borrow checker - // by taking out two references to a mutable value - let mut d2 = data.clone(); - assert_eq!(data.pointer_mut("").unwrap(), &mut d2); -} - -#[test] -fn test_stack_overflow() { - let brackets: String = iter::repeat('[') - .take(127) - .chain(iter::repeat(']').take(127)) - .collect(); - let _: Value = from_str(&brackets).unwrap(); - - let brackets: String = iter::repeat('[').take(129).collect(); - test_parse_err::(&[(&brackets, "recursion limit exceeded at line 1 column 128")]); -} - -#[test] -#[cfg(feature = "unbounded_depth")] -fn test_disable_recursion_limit() { - let brackets: String = iter::repeat('[') - .take(140) - .chain(iter::repeat(']').take(140)) - .collect(); - - let mut deserializer = Deserializer::from_str(&brackets); - deserializer.disable_recursion_limit(); - Value::deserialize(&mut deserializer).unwrap(); -} - -#[test] -fn test_integer_key() { - // map with integer keys - let map = treemap!( - 1 => 2, - -1 => 6 - ); - let j = r#"{"-1":6,"1":2}"#; - test_encode_ok(&[(&map, j)]); - test_parse_ok(vec![(j, map)]); - - let j = r#"{"x":null}"#; - test_parse_err::>(&[( - j, - "invalid type: string \"x\", expected i32 at line 1 column 4", - )]); -} - -#[test] -fn test_integer128_key() { - let map = treemap! { - 100000000000000000000000000000000000000u128 => () - }; - let j = r#"{"100000000000000000000000000000000000000":null}"#; - assert_eq!(to_string(&map).unwrap(), j); - assert_eq!(from_str::>(j).unwrap(), map); -} - -#[test] -fn test_deny_float_key() { - #[derive(Eq, PartialEq, Ord, PartialOrd)] - struct Float; - impl Serialize for Float { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_f32(1.0) - } - } - - // map with float key - let map = treemap!(Float => "x"); - assert!(serde_json::to_value(&map).is_err()); -} - -#[test] -fn test_borrowed_key() { - let map: BTreeMap<&str, ()> = from_str("{\"borrowed\":null}").unwrap(); - let expected = treemap! { "borrowed" => () }; - assert_eq!(map, expected); - - #[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq)] - struct NewtypeStr<'a>(&'a str); - - let map: BTreeMap = from_str("{\"borrowed\":null}").unwrap(); - let expected = treemap! { NewtypeStr("borrowed") => () }; - assert_eq!(map, expected); -} - -#[test] -fn test_effectively_string_keys() { - #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)] - enum Enum { - One, - Two, - } - let map = treemap! { - Enum::One => 1, - Enum::Two => 2 - }; - let expected = r#"{"One":1,"Two":2}"#; - test_encode_ok(&[(&map, expected)]); - test_parse_ok(vec![(expected, map)]); - - #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)] - struct Wrapper(String); - let map = treemap! { - Wrapper("zero".to_owned()) => 0, - Wrapper("one".to_owned()) => 1 - }; - let expected = r#"{"one":1,"zero":0}"#; - test_encode_ok(&[(&map, expected)]); - test_parse_ok(vec![(expected, map)]); -} - -#[test] -fn test_json_macro() { - // This is tricky because the <...> is not a single TT and the comma inside - // looks like an array element separator. - let _ = json!([ - as Clone>::clone(&Ok(())), - as Clone>::clone(&Err(())) - ]); - - // Same thing but in the map values. - let _ = json!({ - "ok": as Clone>::clone(&Ok(())), - "err": as Clone>::clone(&Err(())) - }); - - // It works in map keys but only if they are parenthesized. - let _ = json!({ - ( as Clone>::clone(&Ok("")).unwrap()): "ok", - ( as Clone>::clone(&Err("")).unwrap_err()): "err" - }); - - #[deny(unused_results)] - let _ = json!({ "architecture": [true, null] }); -} - -#[test] -fn issue_220() { - #[derive(Debug, PartialEq, Eq, Deserialize)] - enum E { - V(u8), - } - - assert!(from_str::(r#" "V"0 "#).is_err()); - - assert_eq!(from_str::(r#"{"V": 0}"#).unwrap(), E::V(0)); -} - -macro_rules! number_partialeq_ok { - ($($n:expr)*) => { - $( - let value = to_value($n).unwrap(); - let s = $n.to_string(); - assert_eq!(value, $n); - assert_eq!($n, value); - assert_ne!(value, s); - )* - } -} - -#[test] -fn test_partialeq_number() { - number_partialeq_ok!(0 1 100 - i8::MIN i8::MAX i16::MIN i16::MAX i32::MIN i32::MAX i64::MIN i64::MAX - u8::MIN u8::MAX u16::MIN u16::MAX u32::MIN u32::MAX u64::MIN u64::MAX - f32::MIN f32::MAX f32::MIN_EXP f32::MAX_EXP f32::MIN_POSITIVE - f64::MIN f64::MAX f64::MIN_EXP f64::MAX_EXP f64::MIN_POSITIVE - f32::consts::E f32::consts::PI f32::consts::LN_2 f32::consts::LOG2_E - f64::consts::E f64::consts::PI f64::consts::LN_2 f64::consts::LOG2_E - ); -} - -#[test] -#[cfg(integer128)] -#[cfg(feature = "arbitrary_precision")] -fn test_partialeq_integer128() { - number_partialeq_ok!(i128::MIN i128::MAX u128::MIN u128::MAX) -} - -#[test] -fn test_partialeq_string() { - let v = to_value("42").unwrap(); - assert_eq!(v, "42"); - assert_eq!("42", v); - assert_ne!(v, 42); - assert_eq!(v, String::from("42")); - assert_eq!(String::from("42"), v); -} - -#[test] -fn test_partialeq_bool() { - let v = to_value(true).unwrap(); - assert_eq!(v, true); - assert_eq!(true, v); - assert_ne!(v, false); - assert_ne!(v, "true"); - assert_ne!(v, 1); - assert_ne!(v, 0); -} - -struct FailReader(io::ErrorKind); - -impl io::Read for FailReader { - fn read(&mut self, _: &mut [u8]) -> io::Result { - Err(io::Error::new(self.0, "oh no!")) - } -} - -#[test] -fn test_category() { - assert!(from_str::("123").unwrap_err().is_data()); - - assert!(from_str::("]").unwrap_err().is_syntax()); - - assert!(from_str::("").unwrap_err().is_eof()); - assert!(from_str::("\"").unwrap_err().is_eof()); - assert!(from_str::("\"\\").unwrap_err().is_eof()); - assert!(from_str::("\"\\u").unwrap_err().is_eof()); - assert!(from_str::("\"\\u0").unwrap_err().is_eof()); - assert!(from_str::("\"\\u00").unwrap_err().is_eof()); - assert!(from_str::("\"\\u000").unwrap_err().is_eof()); - - assert!(from_str::>("[").unwrap_err().is_eof()); - assert!(from_str::>("[0").unwrap_err().is_eof()); - assert!(from_str::>("[0,").unwrap_err().is_eof()); - - assert!(from_str::>("{") - .unwrap_err() - .is_eof()); - assert!(from_str::>("{\"k\"") - .unwrap_err() - .is_eof()); - assert!(from_str::>("{\"k\":") - .unwrap_err() - .is_eof()); - assert!(from_str::>("{\"k\":0") - .unwrap_err() - .is_eof()); - assert!(from_str::>("{\"k\":0,") - .unwrap_err() - .is_eof()); - - let fail = FailReader(io::ErrorKind::NotConnected); - assert!(from_reader::<_, String>(fail).unwrap_err().is_io()); -} - -#[test] -// Clippy false positive: https://github.com/Manishearth/rust-clippy/issues/292 -#[allow(clippy::needless_lifetimes)] -fn test_into_io_error() { - fn io_error<'de, T: Deserialize<'de> + Debug>(j: &'static str) -> io::Error { - from_str::(j).unwrap_err().into() - } - - assert_eq!( - io_error::("\"\\u").kind(), - io::ErrorKind::UnexpectedEof - ); - assert_eq!(io_error::("0").kind(), io::ErrorKind::InvalidData); - assert_eq!(io_error::("]").kind(), io::ErrorKind::InvalidData); - - let fail = FailReader(io::ErrorKind::NotConnected); - let io_err: io::Error = from_reader::<_, u8>(fail).unwrap_err().into(); - assert_eq!(io_err.kind(), io::ErrorKind::NotConnected); -} - -#[test] -fn test_borrow() { - let s: &str = from_str("\"borrowed\"").unwrap(); - assert_eq!("borrowed", s); - - let s: &str = from_slice(b"\"borrowed\"").unwrap(); - assert_eq!("borrowed", s); -} - -#[test] -fn null_invalid_type() { - let err = serde_json::from_str::("null").unwrap_err(); - assert_eq!( - format!("{}", err), - String::from("invalid type: null, expected a string at line 1 column 4") - ); -} - -#[test] -fn test_integer128() { - let signed = &[i128::min_value(), -1, 0, 1, i128::max_value()]; - let unsigned = &[0, 1, u128::max_value()]; - - for integer128 in signed { - let expected = integer128.to_string(); - assert_eq!(to_string(integer128).unwrap(), expected); - assert_eq!(from_str::(&expected).unwrap(), *integer128); - } - - for integer128 in unsigned { - let expected = integer128.to_string(); - assert_eq!(to_string(integer128).unwrap(), expected); - assert_eq!(from_str::(&expected).unwrap(), *integer128); - } - - test_parse_err::(&[ - ( - "-170141183460469231731687303715884105729", - "number out of range at line 1 column 40", - ), - ( - "170141183460469231731687303715884105728", - "number out of range at line 1 column 39", - ), - ]); - - test_parse_err::(&[ - ("-1", "number out of range at line 1 column 1"), - ( - "340282366920938463463374607431768211456", - "number out of range at line 1 column 39", - ), - ]); -} - -#[cfg(feature = "raw_value")] -#[test] -fn test_borrowed_raw_value() { - use serde_json::value::RawValue; - - #[derive(Serialize, Deserialize)] - struct Wrapper<'a> { - a: i8, - #[serde(borrow)] - b: &'a RawValue, - c: i8, - }; - - let wrapper_from_str: Wrapper = - serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap(); - assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get()); - - let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap(); - assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string); - - let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap(); - assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value); - - let array_from_str: Vec<&RawValue> = - serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); - assert_eq!(r#""a""#, array_from_str[0].get()); - assert_eq!(r#"42"#, array_from_str[1].get()); - assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); - assert_eq!(r#"null"#, array_from_str[3].get()); - - let array_to_string = serde_json::to_string(&array_from_str).unwrap(); - assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); -} - -#[cfg(feature = "raw_value")] -#[test] -fn test_boxed_raw_value() { - use serde_json::value::RawValue; - - #[derive(Serialize, Deserialize)] - struct Wrapper { - a: i8, - b: Box, - c: i8, - }; - - let wrapper_from_str: Wrapper = - serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap(); - assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get()); - - let wrapper_from_reader: Wrapper = - serde_json::from_reader(br#"{"a": 1, "b": {"foo": 2}, "c": 3}"#.as_ref()).unwrap(); - assert_eq!(r#"{"foo": 2}"#, wrapper_from_reader.b.get()); - - let wrapper_from_value: Wrapper = - serde_json::from_value(json!({"a": 1, "b": {"foo": 2}, "c": 3})).unwrap(); - assert_eq!(r#"{"foo":2}"#, wrapper_from_value.b.get()); - - let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap(); - assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string); - - let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap(); - assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value); - - let array_from_str: Vec> = - serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap(); - assert_eq!(r#""a""#, array_from_str[0].get()); - assert_eq!(r#"42"#, array_from_str[1].get()); - assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get()); - assert_eq!(r#"null"#, array_from_str[3].get()); - - let array_from_reader: Vec> = - serde_json::from_reader(br#"["a", 42, {"foo": "bar"}, null]"#.as_ref()).unwrap(); - assert_eq!(r#""a""#, array_from_reader[0].get()); - assert_eq!(r#"42"#, array_from_reader[1].get()); - assert_eq!(r#"{"foo": "bar"}"#, array_from_reader[2].get()); - assert_eq!(r#"null"#, array_from_reader[3].get()); - - let array_to_string = serde_json::to_string(&array_from_str).unwrap(); - assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); -} - -#[test] -fn test_borrow_in_map_key() { - #[derive(Deserialize, Debug)] - struct Outer { - map: BTreeMap, - } - - #[derive(Ord, PartialOrd, Eq, PartialEq, Debug)] - struct MyMapKey(usize); - - impl<'de> Deserialize<'de> for MyMapKey { - fn deserialize(deserializer: D) -> Result - where - D: de::Deserializer<'de>, - { - let s = <&str>::deserialize(deserializer)?; - let n = s.parse().map_err(de::Error::custom)?; - Ok(MyMapKey(n)) - } - } - - let value = json!({ "map": { "1": null } }); - Outer::deserialize(&value).unwrap(); -} - -#[test] -fn test_value_into_deserializer() { - #[derive(Deserialize)] - struct Outer { - inner: Inner, - } - - #[derive(Deserialize)] - struct Inner { - string: String, - } - - let mut map = BTreeMap::new(); - map.insert("inner", json!({ "string": "Hello World" })); - - let outer = Outer::deserialize(map.into_deserializer()).unwrap(); - assert_eq!(outer.inner.string, "Hello World"); -} diff --git a/json/tests/ui/missing_colon.rs b/json/tests/ui/missing_colon.rs deleted file mode 100644 index d93b7b90..00000000 --- a/json/tests/ui/missing_colon.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "a" }); -} diff --git a/json/tests/ui/missing_colon.stderr b/json/tests/ui/missing_colon.stderr deleted file mode 100644 index 0402397d..00000000 --- a/json/tests/ui/missing_colon.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: unexpected end of macro invocation - --> $DIR/missing_colon.rs:4:5 - | -4 | json!({ "a" }); - | ^^^^^^^^^^^^^^^ missing tokens in macro arguments - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/json/tests/ui/missing_value.rs b/json/tests/ui/missing_value.rs deleted file mode 100644 index 0ba14e22..00000000 --- a/json/tests/ui/missing_value.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "a" : }); -} diff --git a/json/tests/ui/missing_value.stderr b/json/tests/ui/missing_value.stderr deleted file mode 100644 index 0cf37fc6..00000000 --- a/json/tests/ui/missing_value.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: unexpected end of macro invocation - --> $DIR/missing_value.rs:4:5 - | -4 | json!({ "a" : }); - | ^^^^^^^^^^^^^^^^^ missing tokens in macro arguments - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/json/tests/ui/not_found.rs b/json/tests/ui/not_found.rs deleted file mode 100644 index 2df6870d..00000000 --- a/json/tests/ui/not_found.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "a" : x }); -} diff --git a/json/tests/ui/not_found.stderr b/json/tests/ui/not_found.stderr deleted file mode 100644 index b38f1a3e..00000000 --- a/json/tests/ui/not_found.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error[E0425]: cannot find value `x` in this scope - --> $DIR/not_found.rs:4:19 - | -4 | json!({ "a" : x }); - | ^ not found in this scope diff --git a/json/tests/ui/parse_expr.rs b/json/tests/ui/parse_expr.rs deleted file mode 100644 index e7f1805b..00000000 --- a/json/tests/ui/parse_expr.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "a" : ~ }); -} diff --git a/json/tests/ui/parse_expr.stderr b/json/tests/ui/parse_expr.stderr deleted file mode 100644 index 107ec59e..00000000 --- a/json/tests/ui/parse_expr.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: unexpected end of macro invocation - --> $DIR/parse_expr.rs:4:5 - | -4 | json!({ "a" : ~ }); - | ^^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments - | - = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/json/tests/ui/parse_key.rs b/json/tests/ui/parse_key.rs deleted file mode 100644 index 858bd716..00000000 --- a/json/tests/ui/parse_key.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "".s : true }); -} diff --git a/json/tests/ui/parse_key.stderr b/json/tests/ui/parse_key.stderr deleted file mode 100644 index ea09836c..00000000 --- a/json/tests/ui/parse_key.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error[E0609]: no field `s` on type `&'static str` - --> $DIR/parse_key.rs:4:16 - | -4 | json!({ "".s : true }); - | ^ diff --git a/json/tests/ui/unexpected_after_array_element.rs b/json/tests/ui/unexpected_after_array_element.rs deleted file mode 100644 index 226c58cf..00000000 --- a/json/tests/ui/unexpected_after_array_element.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!([ true => ]); -} diff --git a/json/tests/ui/unexpected_after_array_element.stderr b/json/tests/ui/unexpected_after_array_element.stderr deleted file mode 100644 index 3708992c..00000000 --- a/json/tests/ui/unexpected_after_array_element.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `=>` - --> $DIR/unexpected_after_array_element.rs:4:18 - | -4 | json!([ true => ]); - | ^^ no rules expected this token in macro call diff --git a/json/tests/ui/unexpected_after_map_entry.rs b/json/tests/ui/unexpected_after_map_entry.rs deleted file mode 100644 index 0dfb7315..00000000 --- a/json/tests/ui/unexpected_after_map_entry.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "k": true => }); -} diff --git a/json/tests/ui/unexpected_after_map_entry.stderr b/json/tests/ui/unexpected_after_map_entry.stderr deleted file mode 100644 index 60f9815b..00000000 --- a/json/tests/ui/unexpected_after_map_entry.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `=>` - --> $DIR/unexpected_after_map_entry.rs:4:23 - | -4 | json!({ "k": true => }); - | ^^ no rules expected this token in macro call diff --git a/json/tests/ui/unexpected_colon.rs b/json/tests/ui/unexpected_colon.rs deleted file mode 100644 index e767ea6f..00000000 --- a/json/tests/ui/unexpected_colon.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ : true }); -} diff --git a/json/tests/ui/unexpected_colon.stderr b/json/tests/ui/unexpected_colon.stderr deleted file mode 100644 index 2708b088..00000000 --- a/json/tests/ui/unexpected_colon.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `:` - --> $DIR/unexpected_colon.rs:4:13 - | -4 | json!({ : true }); - | ^ no rules expected this token in macro call diff --git a/json/tests/ui/unexpected_comma.rs b/json/tests/ui/unexpected_comma.rs deleted file mode 100644 index 338874ed..00000000 --- a/json/tests/ui/unexpected_comma.rs +++ /dev/null @@ -1,5 +0,0 @@ -use serde_json::json; - -fn main() { - json!({ "a" , "b": true }); -} diff --git a/json/tests/ui/unexpected_comma.stderr b/json/tests/ui/unexpected_comma.stderr deleted file mode 100644 index 65e04530..00000000 --- a/json/tests/ui/unexpected_comma.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: no rules expected the token `,` - --> $DIR/unexpected_comma.rs:4:17 - | -4 | json!({ "a" , "b": true }); - | ^ no rules expected this token in macro call diff --git a/pyproject.toml b/pyproject.toml index af355001..757cd2c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ requires = ["maturin>=0.11.2,<0.12"] [tool.maturin] manylinux = "off" -sdist-include = ["Cargo.lock", "json/**/*"] +sdist-include = ["Cargo.lock"] strip = "on" [tool.black] diff --git a/src/lib.rs b/src/lib.rs index 9735843c..50ff10fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: (Apache-2.0 OR MIT) -#![feature(core_intrinsics)] +#![cfg_attr(feature = "unstable-simd", feature(core_intrinsics))] #![allow(unused_unsafe)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::redundant_field_names)] diff --git a/src/util.rs b/src/util.rs index 2b8e06fb..56b8cfb9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -18,12 +18,20 @@ macro_rules! err { }; } +#[cfg(feature = "unstable-simd")] macro_rules! unlikely { ($exp:expr) => { core::intrinsics::unlikely($exp) }; } +#[cfg(not(feature = "unstable-simd"))] +macro_rules! unlikely { + ($exp:expr) => { + $exp + }; +} + macro_rules! nonnull { ($exp:expr) => { unsafe { std::ptr::NonNull::new_unchecked($exp) }