├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── fuzz ├── .gitignore ├── Cargo.toml └── fuzz_targets │ └── from_slice.rs ├── src ├── de.rs ├── error.rs ├── io │ ├── core.rs │ └── mod.rs ├── iter.rs ├── lexical │ ├── algorithm.rs │ ├── bhcomp.rs │ ├── bignum.rs │ ├── cached.rs │ ├── cached_float80.rs │ ├── digit.rs │ ├── errors.rs │ ├── exponent.rs │ ├── float.rs │ ├── large_powers.rs │ ├── large_powers32.rs │ ├── large_powers64.rs │ ├── math.rs │ ├── mod.rs │ ├── num.rs │ ├── parse.rs │ ├── rounding.rs │ ├── shift.rs │ └── small_powers.rs ├── lib.rs ├── macros.rs ├── map.rs ├── number.rs ├── raw.rs ├── read.rs ├── ser.rs └── value │ ├── de.rs │ ├── from.rs │ ├── index.rs │ ├── mod.rs │ ├── partial_eq.rs │ └── ser.rs └── tests ├── compiletest.rs ├── crate ├── .gitignore ├── Cargo.toml └── test.rs ├── debug.rs ├── lexical.rs ├── lexical ├── algorithm.rs ├── exponent.rs ├── float.rs ├── math.rs ├── num.rs ├── parse.rs └── rounding.rs ├── macros └── mod.rs ├── map.rs ├── regression.rs ├── regression ├── issue1004.rs ├── issue520.rs ├── issue795.rs ├── issue845.rs └── issue953.rs ├── stream.rs ├── test.rs └── ui ├── missing_colon.rs ├── missing_colon.stderr ├── missing_comma.rs ├── missing_comma.stderr ├── missing_value.rs ├── missing_value.stderr ├── not_found.rs ├── not_found.stderr ├── parse_expr.rs ├── parse_expr.stderr ├── parse_key.rs ├── parse_key.stderr ├── unexpected_after_array_element.rs ├── unexpected_after_array_element.stderr ├── unexpected_after_map_entry.rs ├── unexpected_after_map_entry.stderr ├── unexpected_colon.rs ├── unexpected_colon.stderr ├── unexpected_comma.rs └── unexpected_comma.stderr /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | workflow_dispatch: 7 | schedule: [cron: "40 1 * * *"] 8 | 9 | permissions: 10 | contents: read 11 | 12 | env: 13 | RUSTFLAGS: -Dwarnings 14 | 15 | jobs: 16 | test: 17 | name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}} 18 | runs-on: ${{matrix.os}}-latest 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | os: [ubuntu, windows] 23 | timeout-minutes: 45 24 | steps: 25 | - uses: actions/checkout@v4 26 | - uses: dtolnay/rust-toolchain@nightly 27 | - run: cargo test 28 | - run: cargo test --features preserve_order --tests -- --skip ui --exact 29 | - run: cargo test --features float_roundtrip --tests -- --skip ui --exact 30 | - run: cargo test --features arbitrary_precision --tests -- --skip ui --exact 31 | - run: cargo test --features float_roundtrip,arbitrary_precision --tests -- --skip ui --exact 32 | - run: cargo test --features raw_value --tests -- --skip ui --exact 33 | - run: cargo test --features unbounded_depth --tests -- --skip ui --exact 34 | - uses: actions/upload-artifact@v4 35 | if: matrix.os == 'ubuntu' && always() 36 | with: 37 | name: Cargo.lock 38 | path: Cargo.lock 39 | continue-on-error: true 40 | 41 | build: 42 | name: Rust ${{matrix.rust}} ${{matrix.os == 'windows' && '(windows)' || ''}} 43 | runs-on: ${{matrix.os}}-latest 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | rust: [beta, 1.65.0, 1.56.1] 48 | os: [ubuntu] 49 | include: 50 | - rust: stable 51 | os: ubuntu 52 | target: aarch64-unknown-none 53 | - rust: stable 54 | os: windows 55 | timeout-minutes: 45 56 | steps: 57 | - uses: actions/checkout@v4 58 | - uses: dtolnay/rust-toolchain@master 59 | with: 60 | toolchain: ${{matrix.rust}} 61 | targets: ${{matrix.target}} 62 | - run: cargo check --manifest-path tests/crate/Cargo.toml 63 | - run: cargo check --manifest-path tests/crate/Cargo.toml --features float_roundtrip 64 | - run: cargo check --manifest-path tests/crate/Cargo.toml --features arbitrary_precision 65 | - run: cargo check --manifest-path tests/crate/Cargo.toml --features raw_value 66 | - run: cargo check --manifest-path tests/crate/Cargo.toml --features unbounded_depth 67 | - run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc 68 | - run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,arbitrary_precision 69 | - run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,raw_value 70 | - run: cargo check --manifest-path tests/crate/Cargo.toml --features serde_json/preserve_order 71 | if: matrix.rust != '1.56.1' 72 | - run: cargo check --manifest-path tests/crate/Cargo.toml --no-default-features --features alloc,serde_json/preserve_order 73 | if: matrix.rust != '1.56.1' 74 | - name: Build without std 75 | run: cargo check --manifest-path tests/crate/Cargo.toml --target ${{matrix.target}} --no-default-features --features alloc 76 | if: matrix.target 77 | 78 | minimal: 79 | name: Minimal versions 80 | runs-on: ubuntu-latest 81 | timeout-minutes: 45 82 | steps: 83 | - uses: actions/checkout@v4 84 | - uses: dtolnay/rust-toolchain@nightly 85 | - run: cargo generate-lockfile -Z minimal-versions 86 | - run: cargo check --locked 87 | 88 | miri: 89 | name: Miri (${{matrix.name}}) 90 | runs-on: ubuntu-latest 91 | strategy: 92 | fail-fast: false 93 | matrix: 94 | include: 95 | - name: 64-bit little endian 96 | target: x86_64-unknown-linux-gnu 97 | - name: 64-bit big endian 98 | target: powerpc64-unknown-linux-gnu 99 | - name: 32-bit little endian 100 | target: i686-unknown-linux-gnu 101 | - name: 32-bit big endian 102 | target: mips-unknown-linux-gnu 103 | env: 104 | MIRIFLAGS: -Zmiri-strict-provenance 105 | timeout-minutes: 45 106 | steps: 107 | - uses: actions/checkout@v4 108 | - uses: dtolnay/rust-toolchain@miri 109 | with: 110 | toolchain: nightly-2025-05-16 # https://github.com/rust-lang/miri/issues/4323 111 | - run: cargo miri setup 112 | - run: cargo miri test --target ${{matrix.target}} 113 | - run: cargo miri test --target ${{matrix.target}} --features preserve_order,float_roundtrip,arbitrary_precision,raw_value 114 | 115 | clippy: 116 | name: Clippy 117 | runs-on: ubuntu-latest 118 | if: github.event_name != 'pull_request' 119 | timeout-minutes: 45 120 | steps: 121 | - uses: actions/checkout@v4 122 | - uses: dtolnay/rust-toolchain@clippy 123 | - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic 124 | - run: cargo clippy --all-features --tests -- -Dclippy::all -Dclippy::pedantic 125 | 126 | doc: 127 | name: Documentation 128 | runs-on: ubuntu-latest 129 | timeout-minutes: 45 130 | env: 131 | RUSTDOCFLAGS: -Dwarnings 132 | steps: 133 | - uses: actions/checkout@v4 134 | - uses: dtolnay/rust-toolchain@nightly 135 | - uses: dtolnay/install@cargo-docs-rs 136 | - run: cargo docs-rs 137 | 138 | fuzz: 139 | name: Fuzz 140 | runs-on: ubuntu-latest 141 | timeout-minutes: 45 142 | steps: 143 | - uses: actions/checkout@v4 144 | - uses: dtolnay/rust-toolchain@nightly 145 | - uses: dtolnay/install@cargo-fuzz 146 | - run: cargo fuzz check 147 | 148 | outdated: 149 | name: Outdated 150 | runs-on: ubuntu-latest 151 | if: github.event_name != 'pull_request' 152 | timeout-minutes: 45 153 | steps: 154 | - uses: actions/checkout@v4 155 | - uses: dtolnay/rust-toolchain@stable 156 | - uses: dtolnay/install@cargo-outdated 157 | - run: cargo outdated --exit-code 1 158 | - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1 159 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Serde 2 | 3 | Serde welcomes contribution from everyone in the form of suggestions, bug 4 | reports, pull requests, and feedback. This document gives some guidance if you 5 | are thinking of helping us. 6 | 7 | ## Submitting bug reports and feature requests 8 | 9 | Serde development is spread across lots of repositories. In general, prefer to 10 | open issues against the main [serde-rs/serde] repository unless the topic is 11 | clearly specific to JSON. 12 | 13 | [serde-rs/serde]: https://github.com/serde-rs/serde 14 | 15 | When reporting a bug or asking for help, please include enough details so that 16 | the people helping you can reproduce the behavior you are seeing. For some tips 17 | on how to approach this, read about how to produce a [Minimal, Complete, and 18 | Verifiable example]. 19 | 20 | [Minimal, Complete, and Verifiable example]: https://stackoverflow.com/help/mcve 21 | 22 | When making a feature request, please make it clear what problem you intend to 23 | solve with the feature, any ideas for how Serde could support solving that 24 | problem, any possible alternatives, and any disadvantages. 25 | 26 | ## Running the test suite 27 | 28 | We encourage you to check that the test suite passes locally before submitting a 29 | pull request with your changes. If anything does not pass, typically it will be 30 | easier to iterate and fix it locally than waiting for the CI servers to run 31 | tests for you. 32 | 33 | The test suite requires a nightly compiler. 34 | 35 | ```sh 36 | # Run the full test suite, including doc test and compile-tests 37 | cargo test 38 | ``` 39 | 40 | ## Conduct 41 | 42 | In all Serde-related forums, we follow the [Rust Code of Conduct]. For 43 | escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com) 44 | instead of the Rust moderation team. 45 | 46 | [Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct 47 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json" 3 | version = "1.0.140" 4 | authors = ["Erick Tryzelaar ", "David Tolnay "] 5 | categories = ["encoding", "parser-implementations", "no-std"] 6 | description = "A JSON serialization file format" 7 | documentation = "https://docs.rs/serde_json" 8 | edition = "2021" 9 | keywords = ["json", "serde", "serialization"] 10 | license = "MIT OR Apache-2.0" 11 | repository = "https://github.com/serde-rs/json" 12 | rust-version = "1.56" 13 | 14 | [dependencies] 15 | indexmap = { version = "2.2.3", optional = true } 16 | itoa = "1.0" 17 | memchr = { version = "2", default-features = false } 18 | ryu = "1.0" 19 | serde = { version = "1.0.194", default-features = false } 20 | 21 | [dev-dependencies] 22 | automod = "1.0.11" 23 | indoc = "2.0.2" 24 | ref-cast = "1.0.18" 25 | rustversion = "1.0.13" 26 | serde = { version = "1.0.194", features = ["derive"] } 27 | serde_bytes = "0.11.10" 28 | serde_derive = "1.0.166" 29 | serde_stacker = "0.1.8" 30 | trybuild = { version = "1.0.81", features = ["diff"] } 31 | 32 | [package.metadata.docs.rs] 33 | features = ["preserve_order", "raw_value", "unbounded_depth"] 34 | targets = ["x86_64-unknown-linux-gnu"] 35 | rustdoc-args = [ 36 | "--generate-link-to-definition", 37 | "--extern-html-root-url=core=https://doc.rust-lang.org", 38 | "--extern-html-root-url=alloc=https://doc.rust-lang.org", 39 | "--extern-html-root-url=std=https://doc.rust-lang.org", 40 | ] 41 | 42 | [package.metadata.playground] 43 | features = ["float_roundtrip", "raw_value", "unbounded_depth"] 44 | 45 | 46 | ### FEATURES ################################################################# 47 | 48 | [features] 49 | default = ["std"] 50 | 51 | std = ["memchr/std", "serde/std"] 52 | 53 | # Provide integration for heap-allocated collections without depending on the 54 | # rest of the Rust standard library. 55 | # NOTE: Disabling both `std` *and* `alloc` features is not supported yet. 56 | alloc = ["serde/alloc"] 57 | 58 | # Make serde_json::Map use a representation which maintains insertion order. 59 | # This allows data to be read into a Value and written back to a JSON string 60 | # while preserving the order of map keys in the input. 61 | preserve_order = ["indexmap", "std"] 62 | 63 | # Use sufficient precision when parsing fixed precision floats from JSON to 64 | # ensure that they maintain accuracy when round-tripped through JSON. This comes 65 | # at an approximately 2x performance cost for parsing floats compared to the 66 | # default best-effort precision. 67 | # 68 | # Unlike arbitrary_precision, this feature makes f64 -> JSON -> f64 produce 69 | # output identical to the input. 70 | float_roundtrip = [] 71 | 72 | # Use an arbitrary precision number representation for serde_json::Number. This 73 | # allows JSON numbers of arbitrary size/precision to be read into a Number and 74 | # written back to a JSON string without loss of precision. 75 | # 76 | # Unlike float_roundtrip, this feature makes JSON -> serde_json::Number -> JSON 77 | # produce output identical to the input. 78 | arbitrary_precision = [] 79 | 80 | # Provide a RawValue type that can hold unprocessed JSON during deserialization. 81 | raw_value = [] 82 | 83 | # Provide a method disable_recursion_limit to parse arbitrarily deep JSON 84 | # structures without any consideration for overflowing the stack. When using 85 | # this feature, you will want to provide some other way to protect against stack 86 | # overflows, such as by wrapping your Deserializer in the dynamically growing 87 | # stack adapter provided by the serde_stacker crate. Additionally you will need 88 | # to be careful around other recursive operations on the parsed result which may 89 | # overflow the stack after deserialization has completed, including, but not 90 | # limited to, Display and Debug and Drop impls. 91 | unbounded_depth = [] 92 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Serde JSON   [![Build Status]][actions] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc] 2 | 3 | [Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master 4 | [actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster 5 | [Latest Version]: https://img.shields.io/crates/v/serde_json.svg 6 | [crates.io]: https://crates.io/crates/serde\_json 7 | [Rustc Version 1.36+]: https://img.shields.io/badge/rustc-1.36+-lightgray.svg 8 | [rustc]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html 9 | 10 | **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** 11 | 12 | --- 13 | 14 | ```toml 15 | [dependencies] 16 | serde_json = "1.0" 17 | ``` 18 | 19 | You may be looking for: 20 | 21 | - [JSON API documentation](https://docs.rs/serde_json) 22 | - [Serde API documentation](https://docs.rs/serde) 23 | - [Detailed documentation about Serde](https://serde.rs/) 24 | - [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html) 25 | - [Release notes](https://github.com/serde-rs/json/releases) 26 | 27 | JSON is a ubiquitous open-standard format that uses human-readable text to 28 | transmit data objects consisting of key-value pairs. 29 | 30 | ```json 31 | { 32 | "name": "John Doe", 33 | "age": 43, 34 | "address": { 35 | "street": "10 Downing Street", 36 | "city": "London" 37 | }, 38 | "phones": [ 39 | "+44 1234567", 40 | "+44 2345678" 41 | ] 42 | } 43 | ``` 44 | 45 | There are three common ways that you might find yourself needing to work with 46 | JSON data in Rust. 47 | 48 | - **As text data.** An unprocessed string of JSON data that you receive on an 49 | HTTP endpoint, read from a file, or prepare to send to a remote server. 50 | - **As an untyped or loosely typed representation.** Maybe you want to check 51 | that some JSON data is valid before passing it on, but without knowing the 52 | structure of what it contains. Or you want to do very basic manipulations 53 | like insert a key in a particular spot. 54 | - **As a strongly typed Rust data structure.** When you expect all or most of 55 | your data to conform to a particular structure and want to get real work done 56 | without JSON's loosey-goosey nature tripping you up. 57 | 58 | Serde JSON provides efficient, flexible, safe ways of converting data between 59 | each of these representations. 60 | 61 | ## Operating on untyped JSON values 62 | 63 | Any valid JSON data can be manipulated in the following recursive enum 64 | representation. This data structure is [`serde_json::Value`][value]. 65 | 66 | ```rust 67 | enum Value { 68 | Null, 69 | Bool(bool), 70 | Number(Number), 71 | String(String), 72 | Array(Vec), 73 | Object(Map), 74 | } 75 | ``` 76 | 77 | A string of JSON data can be parsed into a `serde_json::Value` by the 78 | [`serde_json::from_str`][from_str] function. There is also 79 | [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and 80 | [`from_reader`][from_reader] for parsing from any `io::Read` like a File or a 81 | TCP stream. 82 | 83 |
84 | 85 | 86 | 87 |
88 | 89 | ```rust 90 | use serde_json::{Result, Value}; 91 | 92 | fn untyped_example() -> Result<()> { 93 | // Some JSON input data as a &str. Maybe this comes from the user. 94 | let data = r#" 95 | { 96 | "name": "John Doe", 97 | "age": 43, 98 | "phones": [ 99 | "+44 1234567", 100 | "+44 2345678" 101 | ] 102 | }"#; 103 | 104 | // Parse the string of data into serde_json::Value. 105 | let v: Value = serde_json::from_str(data)?; 106 | 107 | // Access parts of the data by indexing with square brackets. 108 | println!("Please call {} at the number {}", v["name"], v["phones"][0]); 109 | 110 | Ok(()) 111 | } 112 | ``` 113 | 114 | The result of square bracket indexing like `v["name"]` is a borrow of the data 115 | at that index, so the type is `&Value`. A JSON map can be indexed with string 116 | keys, while a JSON array can be indexed with integer keys. If the type of the 117 | data is not right for the type with which it is being indexed, or if a map does 118 | not contain the key being indexed, or if the index into a vector is out of 119 | bounds, the returned element is `Value::Null`. 120 | 121 | When a `Value` is printed, it is printed as a JSON string. So in the code above, 122 | the output looks like `Please call "John Doe" at the number "+44 1234567"`. The 123 | quotation marks appear because `v["name"]` is a `&Value` containing a JSON 124 | string and its JSON representation is `"John Doe"`. Printing as a plain string 125 | without quotation marks involves converting from a JSON string to a Rust string 126 | with [`as_str()`] or avoiding the use of `Value` as described in the following 127 | section. 128 | 129 | [`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str 130 | 131 | The `Value` representation is sufficient for very basic tasks but can be tedious 132 | to work with for anything more significant. Error handling is verbose to 133 | implement correctly, for example imagine trying to detect the presence of 134 | unrecognized fields in the input data. The compiler is powerless to help you 135 | when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]` 136 | in one of the dozens of places it is used in your code. 137 | 138 | ## Parsing JSON as strongly typed data structures 139 | 140 | Serde provides a powerful way of mapping JSON data into Rust data structures 141 | largely automatically. 142 | 143 |
144 | 145 | 146 | 147 |
148 | 149 | ```rust 150 | use serde::{Deserialize, Serialize}; 151 | use serde_json::Result; 152 | 153 | #[derive(Serialize, Deserialize)] 154 | struct Person { 155 | name: String, 156 | age: u8, 157 | phones: Vec, 158 | } 159 | 160 | fn typed_example() -> Result<()> { 161 | // Some JSON input data as a &str. Maybe this comes from the user. 162 | let data = r#" 163 | { 164 | "name": "John Doe", 165 | "age": 43, 166 | "phones": [ 167 | "+44 1234567", 168 | "+44 2345678" 169 | ] 170 | }"#; 171 | 172 | // Parse the string of data into a Person object. This is exactly the 173 | // same function as the one that produced serde_json::Value above, but 174 | // now we are asking it for a Person as output. 175 | let p: Person = serde_json::from_str(data)?; 176 | 177 | // Do things just like with any other Rust data structure. 178 | println!("Please call {} at the number {}", p.name, p.phones[0]); 179 | 180 | Ok(()) 181 | } 182 | ``` 183 | 184 | This is the same `serde_json::from_str` function as before, but this time we 185 | assign the return value to a variable of type `Person` so Serde will 186 | automatically interpret the input data as a `Person` and produce informative 187 | error messages if the layout does not conform to what a `Person` is expected to 188 | look like. 189 | 190 | Any type that implements Serde's `Deserialize` trait can be deserialized this 191 | way. This includes built-in Rust standard library types like `Vec` and 192 | `HashMap`, as well as any structs or enums annotated with 193 | `#[derive(Deserialize)]`. 194 | 195 | Once we have `p` of type `Person`, our IDE and the Rust compiler can help us use 196 | it correctly like they do for any other Rust code. The IDE can autocomplete 197 | field names to prevent typos, which was impossible in the `serde_json::Value` 198 | representation. And the Rust compiler can check that when we write 199 | `p.phones[0]`, then `p.phones` is guaranteed to be a `Vec` so indexing 200 | into it makes sense and produces a `String`. 201 | 202 | The necessary setup for using Serde's derive macros is explained on the *[Using 203 | derive]* page of the Serde site. 204 | 205 | [Using derive]: https://serde.rs/derive.html 206 | 207 | ## Constructing JSON values 208 | 209 | Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` 210 | objects with very natural JSON syntax. 211 | 212 |
213 | 214 | 215 | 216 |
217 | 218 | ```rust 219 | use serde_json::json; 220 | 221 | fn main() { 222 | // The type of `john` is `serde_json::Value` 223 | let john = json!({ 224 | "name": "John Doe", 225 | "age": 43, 226 | "phones": [ 227 | "+44 1234567", 228 | "+44 2345678" 229 | ] 230 | }); 231 | 232 | println!("first phone number: {}", john["phones"][0]); 233 | 234 | // Convert to a string of JSON and print it out 235 | println!("{}", john.to_string()); 236 | } 237 | ``` 238 | 239 | The `Value::to_string()` function converts a `serde_json::Value` into a `String` 240 | of JSON text. 241 | 242 | One neat thing about the `json!` macro is that variables and expressions can be 243 | interpolated directly into the JSON value as you are building it. Serde will 244 | check at compile time that the value you are interpolating is able to be 245 | represented as JSON. 246 | 247 |
248 | 249 | 250 | 251 |
252 | 253 | ```rust 254 | let full_name = "John Doe"; 255 | let age_last_year = 42; 256 | 257 | // The type of `john` is `serde_json::Value` 258 | let john = json!({ 259 | "name": full_name, 260 | "age": age_last_year + 1, 261 | "phones": [ 262 | format!("+44 {}", random_phone()) 263 | ] 264 | }); 265 | ``` 266 | 267 | This is amazingly convenient, but we have the problem we had before with 268 | `Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON 269 | provides a better way of serializing strongly-typed data structures into JSON 270 | text. 271 | 272 | ## Creating JSON by serializing data structures 273 | 274 | A data structure can be converted to a JSON string by 275 | [`serde_json::to_string`][to_string]. There is also 276 | [`serde_json::to_vec`][to_vec] which serializes to a `Vec` and 277 | [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` 278 | such as a File or a TCP stream. 279 | 280 |
281 | 282 | 283 | 284 |
285 | 286 | ```rust 287 | use serde::{Deserialize, Serialize}; 288 | use serde_json::Result; 289 | 290 | #[derive(Serialize, Deserialize)] 291 | struct Address { 292 | street: String, 293 | city: String, 294 | } 295 | 296 | fn print_an_address() -> Result<()> { 297 | // Some data structure. 298 | let address = Address { 299 | street: "10 Downing Street".to_owned(), 300 | city: "London".to_owned(), 301 | }; 302 | 303 | // Serialize it to a JSON string. 304 | let j = serde_json::to_string(&address)?; 305 | 306 | // Print, write to a file, or send to an HTTP server. 307 | println!("{}", j); 308 | 309 | Ok(()) 310 | } 311 | ``` 312 | 313 | Any type that implements Serde's `Serialize` trait can be serialized this way. 314 | This includes built-in Rust standard library types like `Vec` and `HashMap`, as well as any structs or enums annotated with `#[derive(Serialize)]`. 316 | 317 | ## Performance 318 | 319 | It is fast. You should expect in the ballpark of 500 to 1000 megabytes per 320 | second deserialization and 600 to 900 megabytes per second serialization, 321 | depending on the characteristics of your data. This is competitive with the 322 | fastest C and C++ JSON libraries or even 30% faster for many use cases. 323 | Benchmarks live in the [serde-rs/json-benchmark] repo. 324 | 325 | [serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark 326 | 327 | ## Getting help 328 | 329 | Serde is one of the most widely used Rust libraries, so any place that 330 | Rustaceans congregate will be able to help you out. For chat, consider trying 331 | the [#rust-questions] or [#rust-beginners] channels of the unofficial community 332 | Discord (invite: ), the [#rust-usage] or 333 | [#beginners] channels of the official Rust Project Discord (invite: 334 | ), or the [#general][zulip] stream in Zulip. For 335 | asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the 336 | [/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust 337 | [Discourse forum][discourse]. It's acceptable to file a support issue in this 338 | repo, but they tend not to get as many eyes as any of the above and may get 339 | closed without a response after some time. 340 | 341 | [#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513 342 | [#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281 343 | [#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848 344 | [#beginners]: https://discord.com/channels/442252698964721669/448238009733742612 345 | [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general 346 | [stackoverflow]: https://stackoverflow.com/questions/tagged/rust 347 | [/r/rust]: https://www.reddit.com/r/rust 348 | [discourse]: https://users.rust-lang.org 349 | 350 | ## No-std support 351 | 352 | As long as there is a memory allocator, it is possible to use serde_json without 353 | the rest of the Rust standard library. Disable the default "std" feature and 354 | enable the "alloc" feature: 355 | 356 | ```toml 357 | [dependencies] 358 | serde_json = { version = "1.0", default-features = false, features = ["alloc"] } 359 | ``` 360 | 361 | For JSON support in Serde without a memory allocator, please see the 362 | [`serde-json-core`] crate. 363 | 364 | [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core 365 | 366 | [value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html 367 | [from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html 368 | [from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html 369 | [from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html 370 | [to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html 371 | [to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html 372 | [to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html 373 | [macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html 374 | 375 |
376 | 377 | #### License 378 | 379 | 380 | Licensed under either of Apache License, Version 381 | 2.0 or MIT license at your option. 382 | 383 | 384 |
385 | 386 | 387 | Unless you explicitly state otherwise, any contribution intentionally submitted 388 | for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 389 | be dual licensed as above, without any additional terms or conditions. 390 | 391 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | println!("cargo:rerun-if-changed=build.rs"); 5 | 6 | println!("cargo:rustc-check-cfg=cfg(fast_arithmetic, values(\"32\", \"64\"))"); 7 | 8 | // Decide ideal limb width for arithmetic in the float parser and string 9 | // parser. 10 | let target_arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap(); 11 | let target_pointer_width = env::var_os("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap(); 12 | if target_arch == "aarch64" 13 | || target_arch == "loongarch64" 14 | || target_arch == "mips64" 15 | || target_arch == "powerpc64" 16 | || target_arch == "wasm32" 17 | || target_arch == "x86_64" 18 | || target_pointer_width == "64" 19 | { 20 | // The above list of architectures are ones that have native support for 21 | // 64-bit arithmetic, but which have some targets using a smaller 22 | // pointer width. Examples include aarch64-unknown-linux-gnu_ilp32 and 23 | // x86_64-unknown-linux-gnux32. So our choice of limb width is not 24 | // equivalent to using usize everywhere. 25 | println!("cargo:rustc-cfg=fast_arithmetic=\"64\""); 26 | } else { 27 | println!("cargo:rustc-cfg=fast_arithmetic=\"32\""); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | /artifacts/ 2 | /corpus/ 3 | /coverage/ 4 | /target/ 5 | /Cargo.lock 6 | -------------------------------------------------------------------------------- /fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json-fuzz" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | libfuzzer-sys = "0.4" 13 | serde_json = { path = ".." } 14 | 15 | [[bin]] 16 | name = "from_slice" 17 | path = "fuzz_targets/from_slice.rs" 18 | test = false 19 | doc = false 20 | -------------------------------------------------------------------------------- /fuzz/fuzz_targets/from_slice.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use libfuzzer_sys::fuzz_target; 4 | use serde_json::{from_slice, Value}; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | _ = from_slice::(data); 8 | }); 9 | -------------------------------------------------------------------------------- /src/io/core.rs: -------------------------------------------------------------------------------- 1 | //! Reimplements core logic and types from `std::io` in an `alloc`-friendly 2 | //! fashion. 3 | 4 | use alloc::vec::Vec; 5 | use core::fmt::{self, Display}; 6 | use core::result; 7 | 8 | pub enum ErrorKind { 9 | Other, 10 | } 11 | 12 | // I/O errors can never occur in no-std mode. All our no-std I/O implementations 13 | // are infallible. 14 | pub struct Error; 15 | 16 | impl Display for Error { 17 | fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 18 | unreachable!() 19 | } 20 | } 21 | 22 | impl Error { 23 | pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error { 24 | Error 25 | } 26 | } 27 | 28 | pub type Result = result::Result; 29 | 30 | pub trait Write { 31 | fn write(&mut self, buf: &[u8]) -> Result; 32 | 33 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 34 | // All our Write impls in no_std mode always write the whole buffer in 35 | // one call infallibly. 36 | let result = self.write(buf); 37 | debug_assert!(result.is_ok()); 38 | debug_assert_eq!(result.unwrap_or(0), buf.len()); 39 | Ok(()) 40 | } 41 | 42 | fn flush(&mut self) -> Result<()>; 43 | } 44 | 45 | impl Write for &mut W { 46 | #[inline] 47 | fn write(&mut self, buf: &[u8]) -> Result { 48 | (*self).write(buf) 49 | } 50 | 51 | #[inline] 52 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 53 | (*self).write_all(buf) 54 | } 55 | 56 | #[inline] 57 | fn flush(&mut self) -> Result<()> { 58 | (*self).flush() 59 | } 60 | } 61 | 62 | impl Write for Vec { 63 | #[inline] 64 | fn write(&mut self, buf: &[u8]) -> Result { 65 | self.extend_from_slice(buf); 66 | Ok(buf.len()) 67 | } 68 | 69 | #[inline] 70 | fn write_all(&mut self, buf: &[u8]) -> Result<()> { 71 | self.extend_from_slice(buf); 72 | Ok(()) 73 | } 74 | 75 | #[inline] 76 | fn flush(&mut self) -> Result<()> { 77 | Ok(()) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/io/mod.rs: -------------------------------------------------------------------------------- 1 | //! A tiny, `no_std`-friendly facade around `std::io`. 2 | //! Reexports types from `std` when available; otherwise reimplements and 3 | //! provides some of the core logic. 4 | //! 5 | //! The main reason that `std::io` hasn't found itself reexported as part of 6 | //! the `core` crate is the `std::io::{Read, Write}` traits' reliance on 7 | //! `std::io::Error`, which may contain internally a heap-allocated `Box` 8 | //! and/or now relying on OS-specific `std::backtrace::Backtrace`. 9 | 10 | pub use self::imp::{Error, ErrorKind, Result, Write}; 11 | 12 | #[cfg(not(feature = "std"))] 13 | #[path = "core.rs"] 14 | mod imp; 15 | 16 | #[cfg(feature = "std")] 17 | use std::io as imp; 18 | 19 | #[cfg(feature = "std")] 20 | pub use std::io::{Bytes, Read}; 21 | -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | use crate::io; 2 | 3 | pub struct LineColIterator { 4 | iter: I, 5 | 6 | /// Index of the current line. Characters in the first line of the input 7 | /// (before the first newline character) are in line 1. 8 | line: usize, 9 | 10 | /// Index of the current column. The first character in the input and any 11 | /// characters immediately following a newline character are in column 1. 12 | /// The column is 0 immediately after a newline character has been read. 13 | col: usize, 14 | 15 | /// Byte offset of the start of the current line. This is the sum of lengths 16 | /// of all previous lines. Keeping track of things this way allows efficient 17 | /// computation of the current line, column, and byte offset while only 18 | /// updating one of the counters in `next()` in the common case. 19 | start_of_line: usize, 20 | } 21 | 22 | impl LineColIterator 23 | where 24 | I: Iterator>, 25 | { 26 | pub fn new(iter: I) -> LineColIterator { 27 | LineColIterator { 28 | iter, 29 | line: 1, 30 | col: 0, 31 | start_of_line: 0, 32 | } 33 | } 34 | 35 | pub fn line(&self) -> usize { 36 | self.line 37 | } 38 | 39 | pub fn col(&self) -> usize { 40 | self.col 41 | } 42 | 43 | pub fn byte_offset(&self) -> usize { 44 | self.start_of_line + self.col 45 | } 46 | } 47 | 48 | impl Iterator for LineColIterator 49 | where 50 | I: Iterator>, 51 | { 52 | type Item = io::Result; 53 | 54 | fn next(&mut self) -> Option> { 55 | match self.iter.next() { 56 | None => None, 57 | Some(Ok(b'\n')) => { 58 | self.start_of_line += self.col + 1; 59 | self.line += 1; 60 | self.col = 0; 61 | Some(Ok(b'\n')) 62 | } 63 | Some(Ok(c)) => { 64 | self.col += 1; 65 | Some(Ok(c)) 66 | } 67 | Some(Err(e)) => Some(Err(e)), 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/lexical/algorithm.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Algorithms to efficiently convert strings to floats. 4 | 5 | use super::bhcomp::*; 6 | use super::cached::*; 7 | use super::errors::*; 8 | use super::float::ExtendedFloat; 9 | use super::num::*; 10 | use super::small_powers::*; 11 | 12 | // FAST 13 | // ---- 14 | 15 | /// Convert mantissa to exact value for a non-base2 power. 16 | /// 17 | /// Returns the resulting float and if the value can be represented exactly. 18 | pub(crate) fn fast_path(mantissa: u64, exponent: i32) -> Option 19 | where 20 | F: Float, 21 | { 22 | // `mantissa >> (F::MANTISSA_SIZE+1) != 0` effectively checks if the 23 | // value has a no bits above the hidden bit, which is what we want. 24 | let (min_exp, max_exp) = F::exponent_limit(); 25 | let shift_exp = F::mantissa_limit(); 26 | let mantissa_size = F::MANTISSA_SIZE + 1; 27 | if mantissa == 0 { 28 | Some(F::ZERO) 29 | } else if mantissa >> mantissa_size != 0 { 30 | // Would require truncation of the mantissa. 31 | None 32 | } else if exponent == 0 { 33 | // 0 exponent, same as value, exact representation. 34 | let float = F::as_cast(mantissa); 35 | Some(float) 36 | } else if exponent >= min_exp && exponent <= max_exp { 37 | // Value can be exactly represented, return the value. 38 | // Do not use powi, since powi can incrementally introduce 39 | // error. 40 | let float = F::as_cast(mantissa); 41 | Some(float.pow10(exponent)) 42 | } else if exponent >= 0 && exponent <= max_exp + shift_exp { 43 | // Check to see if we have a disguised fast-path, where the 44 | // number of digits in the mantissa is very small, but and 45 | // so digits can be shifted from the exponent to the mantissa. 46 | // https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/ 47 | let small_powers = POW10_64; 48 | let shift = exponent - max_exp; 49 | let power = small_powers[shift as usize]; 50 | 51 | // Compute the product of the power, if it overflows, 52 | // prematurely return early, otherwise, if we didn't overshoot, 53 | // we can get an exact value. 54 | let value = match mantissa.checked_mul(power) { 55 | None => return None, 56 | Some(value) => value, 57 | }; 58 | if value >> mantissa_size != 0 { 59 | None 60 | } else { 61 | // Use powi, since it's correct, and faster on 62 | // the fast-path. 63 | let float = F::as_cast(value); 64 | Some(float.pow10(max_exp)) 65 | } 66 | } else { 67 | // Cannot be exactly represented, exponent too small or too big, 68 | // would require truncation. 69 | None 70 | } 71 | } 72 | 73 | // MODERATE 74 | // -------- 75 | 76 | /// Multiply the floating-point by the exponent. 77 | /// 78 | /// Multiply by pre-calculated powers of the base, modify the extended- 79 | /// float, and return if new value and if the value can be represented 80 | /// accurately. 81 | fn multiply_exponent_extended(fp: &mut ExtendedFloat, exponent: i32, truncated: bool) -> bool 82 | where 83 | F: Float, 84 | { 85 | let powers = ExtendedFloat::get_powers(); 86 | let exponent = exponent.saturating_add(powers.bias); 87 | let small_index = exponent % powers.step; 88 | let large_index = exponent / powers.step; 89 | if exponent < 0 { 90 | // Guaranteed underflow (assign 0). 91 | fp.mant = 0; 92 | true 93 | } else if large_index as usize >= powers.large.len() { 94 | // Overflow (assign infinity) 95 | fp.mant = 1 << 63; 96 | fp.exp = 0x7FF; 97 | true 98 | } else { 99 | // Within the valid exponent range, multiply by the large and small 100 | // exponents and return the resulting value. 101 | 102 | // Track errors to as a factor of unit in last-precision. 103 | let mut errors: u32 = 0; 104 | if truncated { 105 | errors += u64::error_halfscale(); 106 | } 107 | 108 | // Multiply by the small power. 109 | // Check if we can directly multiply by an integer, if not, 110 | // use extended-precision multiplication. 111 | match fp 112 | .mant 113 | .overflowing_mul(powers.get_small_int(small_index as usize)) 114 | { 115 | // Overflow, multiplication unsuccessful, go slow path. 116 | (_, true) => { 117 | fp.normalize(); 118 | fp.imul(&powers.get_small(small_index as usize)); 119 | errors += u64::error_halfscale(); 120 | } 121 | // No overflow, multiplication successful. 122 | (mant, false) => { 123 | fp.mant = mant; 124 | fp.normalize(); 125 | } 126 | } 127 | 128 | // Multiply by the large power 129 | fp.imul(&powers.get_large(large_index as usize)); 130 | if errors > 0 { 131 | errors += 1; 132 | } 133 | errors += u64::error_halfscale(); 134 | 135 | // Normalize the floating point (and the errors). 136 | let shift = fp.normalize(); 137 | errors <<= shift; 138 | 139 | u64::error_is_accurate::(errors, fp) 140 | } 141 | } 142 | 143 | /// Create a precise native float using an intermediate extended-precision float. 144 | /// 145 | /// Return the float approximation and if the value can be accurately 146 | /// represented with mantissa bits of precision. 147 | #[inline] 148 | pub(crate) fn moderate_path( 149 | mantissa: u64, 150 | exponent: i32, 151 | truncated: bool, 152 | ) -> (ExtendedFloat, bool) 153 | where 154 | F: Float, 155 | { 156 | let mut fp = ExtendedFloat { 157 | mant: mantissa, 158 | exp: 0, 159 | }; 160 | let valid = multiply_exponent_extended::(&mut fp, exponent, truncated); 161 | (fp, valid) 162 | } 163 | 164 | // FALLBACK 165 | // -------- 166 | 167 | /// Fallback path when the fast path does not work. 168 | /// 169 | /// Uses the moderate path, if applicable, otherwise, uses the slow path 170 | /// as required. 171 | pub(crate) fn fallback_path( 172 | integer: &[u8], 173 | fraction: &[u8], 174 | mantissa: u64, 175 | exponent: i32, 176 | mantissa_exponent: i32, 177 | truncated: bool, 178 | ) -> F 179 | where 180 | F: Float, 181 | { 182 | // Moderate path (use an extended 80-bit representation). 183 | let (fp, valid) = moderate_path::(mantissa, mantissa_exponent, truncated); 184 | if valid { 185 | return fp.into_float::(); 186 | } 187 | 188 | // Slow path, fast path didn't work. 189 | let b = fp.into_downward_float::(); 190 | if b.is_special() { 191 | // We have a non-finite number, we get to leave early. 192 | b 193 | } else { 194 | bhcomp(b, integer, fraction, exponent) 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/lexical/bhcomp.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Compare the mantissa to the halfway representation of the float. 4 | //! 5 | //! Compares the actual significant digits of the mantissa to the 6 | //! theoretical digits from `b+h`, scaled into the proper range. 7 | 8 | use super::bignum::*; 9 | use super::digit::*; 10 | use super::exponent::*; 11 | use super::float::*; 12 | use super::math::*; 13 | use super::num::*; 14 | use super::rounding::*; 15 | use core::{cmp, mem}; 16 | 17 | // MANTISSA 18 | 19 | /// Parse the full mantissa into a big integer. 20 | /// 21 | /// Max digits is the maximum number of digits plus one. 22 | fn parse_mantissa(integer: &[u8], fraction: &[u8]) -> Bigint 23 | where 24 | F: Float, 25 | { 26 | // Main loop 27 | let small_powers = POW10_LIMB; 28 | let step = small_powers.len() - 2; 29 | let max_digits = F::MAX_DIGITS - 1; 30 | let mut counter = 0; 31 | let mut value: Limb = 0; 32 | let mut i: usize = 0; 33 | let mut result = Bigint::default(); 34 | 35 | // Iteratively process all the data in the mantissa. 36 | for &digit in integer.iter().chain(fraction) { 37 | // We've parsed the max digits using small values, add to bignum 38 | if counter == step { 39 | result.imul_small(small_powers[counter]); 40 | result.iadd_small(value); 41 | counter = 0; 42 | value = 0; 43 | } 44 | 45 | value *= 10; 46 | value += as_limb(to_digit(digit).unwrap()); 47 | 48 | i += 1; 49 | counter += 1; 50 | if i == max_digits { 51 | break; 52 | } 53 | } 54 | 55 | // We will always have a remainder, as long as we entered the loop 56 | // once, or counter % step is 0. 57 | if counter != 0 { 58 | result.imul_small(small_powers[counter]); 59 | result.iadd_small(value); 60 | } 61 | 62 | // If we have any remaining digits after the last value, we need 63 | // to add a 1 after the rest of the array, it doesn't matter where, 64 | // just move it up. This is good for the worst-possible float 65 | // representation. We also need to return an index. 66 | // Since we already trimmed trailing zeros, we know there has 67 | // to be a non-zero digit if there are any left. 68 | if i < integer.len() + fraction.len() { 69 | result.imul_small(10); 70 | result.iadd_small(1); 71 | } 72 | 73 | result 74 | } 75 | 76 | // FLOAT OPS 77 | 78 | /// Calculate `b` from a representation of `b` as a float. 79 | #[inline] 80 | pub(super) fn b_extended(f: F) -> ExtendedFloat { 81 | ExtendedFloat::from_float(f) 82 | } 83 | 84 | /// Calculate `b+h` from a representation of `b` as a float. 85 | #[inline] 86 | pub(super) fn bh_extended(f: F) -> ExtendedFloat { 87 | // None of these can overflow. 88 | let b = b_extended(f); 89 | ExtendedFloat { 90 | mant: (b.mant << 1) + 1, 91 | exp: b.exp - 1, 92 | } 93 | } 94 | 95 | // ROUNDING 96 | 97 | /// Custom round-nearest, tie-event algorithm for bhcomp. 98 | #[inline] 99 | fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32, is_truncated: bool) { 100 | let (mut is_above, mut is_halfway) = round_nearest(fp, shift); 101 | if is_halfway && is_truncated { 102 | is_above = true; 103 | is_halfway = false; 104 | } 105 | tie_even(fp, is_above, is_halfway); 106 | } 107 | 108 | // BHCOMP 109 | 110 | /// Calculate the mantissa for a big integer with a positive exponent. 111 | fn large_atof(mantissa: Bigint, exponent: i32) -> F 112 | where 113 | F: Float, 114 | { 115 | let bits = mem::size_of::() * 8; 116 | 117 | // Simple, we just need to multiply by the power of the radix. 118 | // Now, we can calculate the mantissa and the exponent from this. 119 | // The binary exponent is the binary exponent for the mantissa 120 | // shifted to the hidden bit. 121 | let mut bigmant = mantissa; 122 | bigmant.imul_pow10(exponent as u32); 123 | 124 | // Get the exact representation of the float from the big integer. 125 | let (mant, is_truncated) = bigmant.hi64(); 126 | let exp = bigmant.bit_length() as i32 - bits as i32; 127 | let mut fp = ExtendedFloat { mant, exp }; 128 | fp.round_to_native::(|fp, shift| round_nearest_tie_even(fp, shift, is_truncated)); 129 | into_float(fp) 130 | } 131 | 132 | /// Calculate the mantissa for a big integer with a negative exponent. 133 | /// 134 | /// This invokes the comparison with `b+h`. 135 | fn small_atof(mantissa: Bigint, exponent: i32, f: F) -> F 136 | where 137 | F: Float, 138 | { 139 | // Get the significant digits and radix exponent for the real digits. 140 | let mut real_digits = mantissa; 141 | let real_exp = exponent; 142 | debug_assert!(real_exp < 0); 143 | 144 | // Get the significant digits and the binary exponent for `b+h`. 145 | let theor = bh_extended(f); 146 | let mut theor_digits = Bigint::from_u64(theor.mant); 147 | let theor_exp = theor.exp; 148 | 149 | // We need to scale the real digits and `b+h` digits to be the same 150 | // order. We currently have `real_exp`, in `radix`, that needs to be 151 | // shifted to `theor_digits` (since it is negative), and `theor_exp` 152 | // to either `theor_digits` or `real_digits` as a power of 2 (since it 153 | // may be positive or negative). Try to remove as many powers of 2 154 | // as possible. All values are relative to `theor_digits`, that is, 155 | // reflect the power you need to multiply `theor_digits` by. 156 | 157 | // Can remove a power-of-two, since the radix is 10. 158 | // Both are on opposite-sides of equation, can factor out a 159 | // power of two. 160 | // 161 | // Example: 10^-10, 2^-10 -> ( 0, 10, 0) 162 | // Example: 10^-10, 2^-15 -> (-5, 10, 0) 163 | // Example: 10^-10, 2^-5 -> ( 5, 10, 0) 164 | // Example: 10^-10, 2^5 -> (15, 10, 0) 165 | let binary_exp = theor_exp - real_exp; 166 | let halfradix_exp = -real_exp; 167 | let radix_exp = 0; 168 | 169 | // Carry out our multiplication. 170 | if halfradix_exp != 0 { 171 | theor_digits.imul_pow5(halfradix_exp as u32); 172 | } 173 | if radix_exp != 0 { 174 | theor_digits.imul_pow10(radix_exp as u32); 175 | } 176 | if binary_exp > 0 { 177 | theor_digits.imul_pow2(binary_exp as u32); 178 | } else if binary_exp < 0 { 179 | real_digits.imul_pow2(-binary_exp as u32); 180 | } 181 | 182 | // Compare real digits to theoretical digits and round the float. 183 | match real_digits.compare(&theor_digits) { 184 | cmp::Ordering::Greater => f.next_positive(), 185 | cmp::Ordering::Less => f, 186 | cmp::Ordering::Equal => f.round_positive_even(), 187 | } 188 | } 189 | 190 | /// Calculate the exact value of the float. 191 | /// 192 | /// Note: fraction must not have trailing zeros. 193 | pub(crate) fn bhcomp(b: F, integer: &[u8], mut fraction: &[u8], exponent: i32) -> F 194 | where 195 | F: Float, 196 | { 197 | // Calculate the number of integer digits and use that to determine 198 | // where the significant digits start in the fraction. 199 | let integer_digits = integer.len(); 200 | let fraction_digits = fraction.len(); 201 | let digits_start = if integer_digits == 0 { 202 | let start = fraction.iter().take_while(|&x| *x == b'0').count(); 203 | fraction = &fraction[start..]; 204 | start 205 | } else { 206 | 0 207 | }; 208 | let sci_exp = scientific_exponent(exponent, integer_digits, digits_start); 209 | let count = F::MAX_DIGITS.min(integer_digits + fraction_digits - digits_start); 210 | let scaled_exponent = sci_exp + 1 - count as i32; 211 | 212 | let mantissa = parse_mantissa::(integer, fraction); 213 | if scaled_exponent >= 0 { 214 | large_atof(mantissa, scaled_exponent) 215 | } else { 216 | small_atof(mantissa, scaled_exponent, b) 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /src/lexical/bignum.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Big integer type definition. 4 | 5 | use super::math::*; 6 | #[allow(unused_imports)] 7 | use alloc::vec::Vec; 8 | 9 | /// Storage for a big integer type. 10 | #[derive(Clone, PartialEq, Eq)] 11 | pub(crate) struct Bigint { 12 | /// Internal storage for the Bigint, in little-endian order. 13 | pub(crate) data: Vec, 14 | } 15 | 16 | impl Default for Bigint { 17 | fn default() -> Self { 18 | Bigint { 19 | data: Vec::with_capacity(20), 20 | } 21 | } 22 | } 23 | 24 | impl Math for Bigint { 25 | #[inline] 26 | fn data(&self) -> &Vec { 27 | &self.data 28 | } 29 | 30 | #[inline] 31 | fn data_mut(&mut self) -> &mut Vec { 32 | &mut self.data 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/lexical/cached.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Cached powers trait for extended-precision floats. 4 | 5 | use super::cached_float80; 6 | use super::float::ExtendedFloat; 7 | 8 | // POWERS 9 | 10 | /// Precalculated powers that uses two-separate arrays for memory-efficiency. 11 | #[doc(hidden)] 12 | pub(crate) struct ExtendedFloatArray { 13 | // Pre-calculated mantissa for the powers. 14 | pub mant: &'static [u64], 15 | // Pre-calculated binary exponents for the powers. 16 | pub exp: &'static [i32], 17 | } 18 | 19 | /// Allow indexing of values without bounds checking 20 | impl ExtendedFloatArray { 21 | #[inline] 22 | pub fn get_extended_float(&self, index: usize) -> ExtendedFloat { 23 | let mant = self.mant[index]; 24 | let exp = self.exp[index]; 25 | ExtendedFloat { mant, exp } 26 | } 27 | 28 | #[inline] 29 | pub fn len(&self) -> usize { 30 | self.mant.len() 31 | } 32 | } 33 | 34 | // MODERATE PATH POWERS 35 | 36 | /// Precalculated powers of base N for the moderate path. 37 | #[doc(hidden)] 38 | pub(crate) struct ModeratePathPowers { 39 | // Pre-calculated small powers. 40 | pub small: ExtendedFloatArray, 41 | // Pre-calculated large powers. 42 | pub large: ExtendedFloatArray, 43 | /// Pre-calculated small powers as 64-bit integers 44 | pub small_int: &'static [u64], 45 | // Step between large powers and number of small powers. 46 | pub step: i32, 47 | // Exponent bias for the large powers. 48 | pub bias: i32, 49 | } 50 | 51 | /// Allow indexing of values without bounds checking 52 | impl ModeratePathPowers { 53 | #[inline] 54 | pub fn get_small(&self, index: usize) -> ExtendedFloat { 55 | self.small.get_extended_float(index) 56 | } 57 | 58 | #[inline] 59 | pub fn get_large(&self, index: usize) -> ExtendedFloat { 60 | self.large.get_extended_float(index) 61 | } 62 | 63 | #[inline] 64 | pub fn get_small_int(&self, index: usize) -> u64 { 65 | self.small_int[index] 66 | } 67 | } 68 | 69 | // CACHED EXTENDED POWERS 70 | 71 | /// Cached powers as a trait for a floating-point type. 72 | pub(crate) trait ModeratePathCache { 73 | /// Get cached powers. 74 | fn get_powers() -> &'static ModeratePathPowers; 75 | } 76 | 77 | impl ModeratePathCache for ExtendedFloat { 78 | #[inline] 79 | fn get_powers() -> &'static ModeratePathPowers { 80 | cached_float80::get_powers() 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/lexical/cached_float80.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Cached exponents for basen values with 80-bit extended floats. 4 | //! 5 | //! Exact versions of base**n as an extended-precision float, with both 6 | //! large and small powers. Use the large powers to minimize the amount 7 | //! of compounded error. 8 | //! 9 | //! These values were calculated using Python, using the arbitrary-precision 10 | //! integer to calculate exact extended-representation of each value. 11 | //! These values are all normalized. 12 | 13 | use super::cached::{ExtendedFloatArray, ModeratePathPowers}; 14 | 15 | // LOW-LEVEL 16 | // --------- 17 | 18 | // BASE10 19 | 20 | const BASE10_SMALL_MANTISSA: [u64; 10] = [ 21 | 9223372036854775808, // 10^0 22 | 11529215046068469760, // 10^1 23 | 14411518807585587200, // 10^2 24 | 18014398509481984000, // 10^3 25 | 11258999068426240000, // 10^4 26 | 14073748835532800000, // 10^5 27 | 17592186044416000000, // 10^6 28 | 10995116277760000000, // 10^7 29 | 13743895347200000000, // 10^8 30 | 17179869184000000000, // 10^9 31 | ]; 32 | const BASE10_SMALL_EXPONENT: [i32; 10] = [ 33 | -63, // 10^0 34 | -60, // 10^1 35 | -57, // 10^2 36 | -54, // 10^3 37 | -50, // 10^4 38 | -47, // 10^5 39 | -44, // 10^6 40 | -40, // 10^7 41 | -37, // 10^8 42 | -34, // 10^9 43 | ]; 44 | const BASE10_LARGE_MANTISSA: [u64; 66] = [ 45 | 11555125961253852697, // 10^-350 46 | 13451937075301367670, // 10^-340 47 | 15660115838168849784, // 10^-330 48 | 18230774251475056848, // 10^-320 49 | 10611707258198326947, // 10^-310 50 | 12353653155963782858, // 10^-300 51 | 14381545078898527261, // 10^-290 52 | 16742321987285426889, // 10^-280 53 | 9745314011399999080, // 10^-270 54 | 11345038669416679861, // 10^-260 55 | 13207363278391631158, // 10^-250 56 | 15375394465392026070, // 10^-240 57 | 17899314949046850752, // 10^-230 58 | 10418772551374772303, // 10^-220 59 | 12129047596099288555, // 10^-210 60 | 14120069793541087484, // 10^-200 61 | 16437924692338667210, // 10^-190 62 | 9568131466127621947, // 10^-180 63 | 11138771039116687545, // 10^-170 64 | 12967236152753102995, // 10^-160 65 | 15095849699286165408, // 10^-150 66 | 17573882009934360870, // 10^-140 67 | 10229345649675443343, // 10^-130 68 | 11908525658859223294, // 10^-120 69 | 13863348470604074297, // 10^-110 70 | 16139061738043178685, // 10^-100 71 | 9394170331095332911, // 10^-90 72 | 10936253623915059621, // 10^-80 73 | 12731474852090538039, // 10^-70 74 | 14821387422376473014, // 10^-60 75 | 17254365866976409468, // 10^-50 76 | 10043362776618689222, // 10^-40 77 | 11692013098647223345, // 10^-30 78 | 13611294676837538538, // 10^-20 79 | 15845632502852867518, // 10^-10 80 | 9223372036854775808, // 10^0 81 | 10737418240000000000, // 10^10 82 | 12500000000000000000, // 10^20 83 | 14551915228366851806, // 10^30 84 | 16940658945086006781, // 10^40 85 | 9860761315262647567, // 10^50 86 | 11479437019748901445, // 10^60 87 | 13363823550460978230, // 10^70 88 | 15557538194652854267, // 10^80 89 | 18111358157653424735, // 10^90 90 | 10542197943230523224, // 10^100 91 | 12272733663244316382, // 10^110 92 | 14287342391028437277, // 10^120 93 | 16632655625031838749, // 10^130 94 | 9681479787123295682, // 10^140 95 | 11270725851789228247, // 10^150 96 | 13120851772591970218, // 10^160 97 | 15274681817498023410, // 10^170 98 | 17782069995880619867, // 10^180 99 | 10350527006597618960, // 10^190 100 | 12049599325514420588, // 10^200 101 | 14027579833653779454, // 10^210 102 | 16330252207878254650, // 10^220 103 | 9505457831475799117, // 10^230 104 | 11065809325636130661, // 10^240 105 | 12882297539194266616, // 10^250 106 | 14996968138956309548, // 10^260 107 | 17458768723248864463, // 10^270 108 | 10162340898095201970, // 10^280 109 | 11830521861667747109, // 10^290 110 | 13772540099066387756, // 10^300 111 | ]; 112 | const BASE10_LARGE_EXPONENT: [i32; 66] = [ 113 | -1226, // 10^-350 114 | -1193, // 10^-340 115 | -1160, // 10^-330 116 | -1127, // 10^-320 117 | -1093, // 10^-310 118 | -1060, // 10^-300 119 | -1027, // 10^-290 120 | -994, // 10^-280 121 | -960, // 10^-270 122 | -927, // 10^-260 123 | -894, // 10^-250 124 | -861, // 10^-240 125 | -828, // 10^-230 126 | -794, // 10^-220 127 | -761, // 10^-210 128 | -728, // 10^-200 129 | -695, // 10^-190 130 | -661, // 10^-180 131 | -628, // 10^-170 132 | -595, // 10^-160 133 | -562, // 10^-150 134 | -529, // 10^-140 135 | -495, // 10^-130 136 | -462, // 10^-120 137 | -429, // 10^-110 138 | -396, // 10^-100 139 | -362, // 10^-90 140 | -329, // 10^-80 141 | -296, // 10^-70 142 | -263, // 10^-60 143 | -230, // 10^-50 144 | -196, // 10^-40 145 | -163, // 10^-30 146 | -130, // 10^-20 147 | -97, // 10^-10 148 | -63, // 10^0 149 | -30, // 10^10 150 | 3, // 10^20 151 | 36, // 10^30 152 | 69, // 10^40 153 | 103, // 10^50 154 | 136, // 10^60 155 | 169, // 10^70 156 | 202, // 10^80 157 | 235, // 10^90 158 | 269, // 10^100 159 | 302, // 10^110 160 | 335, // 10^120 161 | 368, // 10^130 162 | 402, // 10^140 163 | 435, // 10^150 164 | 468, // 10^160 165 | 501, // 10^170 166 | 534, // 10^180 167 | 568, // 10^190 168 | 601, // 10^200 169 | 634, // 10^210 170 | 667, // 10^220 171 | 701, // 10^230 172 | 734, // 10^240 173 | 767, // 10^250 174 | 800, // 10^260 175 | 833, // 10^270 176 | 867, // 10^280 177 | 900, // 10^290 178 | 933, // 10^300 179 | ]; 180 | const BASE10_SMALL_INT_POWERS: [u64; 10] = [ 181 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 182 | ]; 183 | const BASE10_STEP: i32 = 10; 184 | const BASE10_BIAS: i32 = 350; 185 | 186 | // HIGH LEVEL 187 | // ---------- 188 | 189 | const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers { 190 | small: ExtendedFloatArray { 191 | mant: &BASE10_SMALL_MANTISSA, 192 | exp: &BASE10_SMALL_EXPONENT, 193 | }, 194 | large: ExtendedFloatArray { 195 | mant: &BASE10_LARGE_MANTISSA, 196 | exp: &BASE10_LARGE_EXPONENT, 197 | }, 198 | small_int: &BASE10_SMALL_INT_POWERS, 199 | step: BASE10_STEP, 200 | bias: BASE10_BIAS, 201 | }; 202 | 203 | /// Get powers from base. 204 | pub(crate) fn get_powers() -> &'static ModeratePathPowers { 205 | &BASE10_POWERS 206 | } 207 | -------------------------------------------------------------------------------- /src/lexical/digit.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Helpers to convert and add digits from characters. 4 | 5 | // Convert u8 to digit. 6 | #[inline] 7 | pub(crate) fn to_digit(c: u8) -> Option { 8 | (c as char).to_digit(10) 9 | } 10 | 11 | // Add digit to mantissa. 12 | #[inline] 13 | pub(crate) fn add_digit(value: u64, digit: u32) -> Option { 14 | match value.checked_mul(10) { 15 | None => None, 16 | Some(n) => n.checked_add(digit as u64), 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/lexical/errors.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Estimate the error in an 80-bit approximation of a float. 4 | //! 5 | //! This estimates the error in a floating-point representation. 6 | //! 7 | //! This implementation is loosely based off the Golang implementation, 8 | //! found here: 9 | 10 | use super::float::*; 11 | use super::num::*; 12 | use super::rounding::*; 13 | 14 | pub(crate) trait FloatErrors { 15 | /// Get the full error scale. 16 | fn error_scale() -> u32; 17 | /// Get the half error scale. 18 | fn error_halfscale() -> u32; 19 | /// Determine if the number of errors is tolerable for float precision. 20 | fn error_is_accurate(count: u32, fp: &ExtendedFloat) -> bool; 21 | } 22 | 23 | /// Check if the error is accurate with a round-nearest rounding scheme. 24 | #[inline] 25 | fn nearest_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool { 26 | // Round-to-nearest, need to use the halfway point. 27 | if extrabits == 65 { 28 | // Underflow, we have a shift larger than the mantissa. 29 | // Representation is valid **only** if the value is close enough 30 | // overflow to the next bit within errors. If it overflows, 31 | // the representation is **not** valid. 32 | !fp.mant.overflowing_add(errors).1 33 | } else { 34 | let mask: u64 = lower_n_mask(extrabits); 35 | let extra: u64 = fp.mant & mask; 36 | 37 | // Round-to-nearest, need to check if we're close to halfway. 38 | // IE, b10100 | 100000, where `|` signifies the truncation point. 39 | let halfway: u64 = lower_n_halfway(extrabits); 40 | let cmp1 = halfway.wrapping_sub(errors) < extra; 41 | let cmp2 = extra < halfway.wrapping_add(errors); 42 | 43 | // If both comparisons are true, we have significant rounding error, 44 | // and the value cannot be exactly represented. Otherwise, the 45 | // representation is valid. 46 | !(cmp1 && cmp2) 47 | } 48 | } 49 | 50 | impl FloatErrors for u64 { 51 | #[inline] 52 | fn error_scale() -> u32 { 53 | 8 54 | } 55 | 56 | #[inline] 57 | fn error_halfscale() -> u32 { 58 | u64::error_scale() / 2 59 | } 60 | 61 | #[inline] 62 | fn error_is_accurate(count: u32, fp: &ExtendedFloat) -> bool { 63 | // Determine if extended-precision float is a good approximation. 64 | // If the error has affected too many units, the float will be 65 | // inaccurate, or if the representation is too close to halfway 66 | // that any operations could affect this halfway representation. 67 | // See the documentation for dtoa for more information. 68 | let bias = -(F::EXPONENT_BIAS - F::MANTISSA_SIZE); 69 | let denormal_exp = bias - 63; 70 | // This is always a valid u32, since (denormal_exp - fp.exp) 71 | // will always be positive and the significand size is {23, 52}. 72 | let extrabits = if fp.exp <= denormal_exp { 73 | 64 - F::MANTISSA_SIZE + denormal_exp - fp.exp 74 | } else { 75 | 63 - F::MANTISSA_SIZE 76 | }; 77 | 78 | // Our logic is as follows: we want to determine if the actual 79 | // mantissa and the errors during calculation differ significantly 80 | // from the rounding point. The rounding point for round-nearest 81 | // is the halfway point, IE, this when the truncated bits start 82 | // with b1000..., while the rounding point for the round-toward 83 | // is when the truncated bits are equal to 0. 84 | // To do so, we can check whether the rounding point +/- the error 85 | // are >/< the actual lower n bits. 86 | // 87 | // For whether we need to use signed or unsigned types for this 88 | // analysis, see this example, using u8 rather than u64 to simplify 89 | // things. 90 | // 91 | // # Comparisons 92 | // cmp1 = (halfway - errors) < extra 93 | // cmp1 = extra < (halfway + errors) 94 | // 95 | // # Large Extrabits, Low Errors 96 | // 97 | // extrabits = 8 98 | // halfway = 0b10000000 99 | // extra = 0b10000010 100 | // errors = 0b00000100 101 | // halfway - errors = 0b01111100 102 | // halfway + errors = 0b10000100 103 | // 104 | // Unsigned: 105 | // halfway - errors = 124 106 | // halfway + errors = 132 107 | // extra = 130 108 | // cmp1 = true 109 | // cmp2 = true 110 | // Signed: 111 | // halfway - errors = 124 112 | // halfway + errors = -124 113 | // extra = -126 114 | // cmp1 = false 115 | // cmp2 = true 116 | // 117 | // # Conclusion 118 | // 119 | // Since errors will always be small, and since we want to detect 120 | // if the representation is accurate, we need to use an **unsigned** 121 | // type for comparisons. 122 | 123 | let extrabits = extrabits as u64; 124 | let errors = count as u64; 125 | if extrabits > 65 { 126 | // Underflow, we have a literal 0. 127 | return true; 128 | } 129 | 130 | nearest_error_is_accurate(errors, fp, extrabits) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/lexical/exponent.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Utilities to calculate exponents. 4 | 5 | /// Convert usize into i32 without overflow. 6 | /// 7 | /// This is needed to ensure when adjusting the exponent relative to 8 | /// the mantissa we do not overflow for comically-long exponents. 9 | #[inline] 10 | fn into_i32(value: usize) -> i32 { 11 | if value > i32::MAX as usize { 12 | i32::MAX 13 | } else { 14 | value as i32 15 | } 16 | } 17 | 18 | // EXPONENT CALCULATION 19 | 20 | // Calculate the scientific notation exponent without overflow. 21 | // 22 | // For example, 0.1 would be -1, and 10 would be 1 in base 10. 23 | #[inline] 24 | pub(crate) fn scientific_exponent( 25 | exponent: i32, 26 | integer_digits: usize, 27 | fraction_start: usize, 28 | ) -> i32 { 29 | if integer_digits == 0 { 30 | let fraction_start = into_i32(fraction_start); 31 | exponent.saturating_sub(fraction_start).saturating_sub(1) 32 | } else { 33 | let integer_shift = into_i32(integer_digits - 1); 34 | exponent.saturating_add(integer_shift) 35 | } 36 | } 37 | 38 | // Calculate the mantissa exponent without overflow. 39 | // 40 | // Remove the number of digits that contributed to the mantissa past 41 | // the dot, and add the number of truncated digits from the mantissa, 42 | // to calculate the scaling factor for the mantissa from a raw exponent. 43 | #[inline] 44 | pub(crate) fn mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i32 { 45 | if fraction_digits > truncated { 46 | exponent.saturating_sub(into_i32(fraction_digits - truncated)) 47 | } else { 48 | exponent.saturating_add(into_i32(truncated - fraction_digits)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/lexical/float.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | // FLOAT TYPE 4 | 5 | use super::num::*; 6 | use super::rounding::*; 7 | use super::shift::*; 8 | 9 | /// Extended precision floating-point type. 10 | /// 11 | /// Private implementation, exposed only for testing purposes. 12 | #[doc(hidden)] 13 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 14 | pub(crate) struct ExtendedFloat { 15 | /// Mantissa for the extended-precision float. 16 | pub mant: u64, 17 | /// Binary exponent for the extended-precision float. 18 | pub exp: i32, 19 | } 20 | 21 | impl ExtendedFloat { 22 | // PROPERTIES 23 | 24 | // OPERATIONS 25 | 26 | /// Multiply two normalized extended-precision floats, as if by `a*b`. 27 | /// 28 | /// The precision is maximal when the numbers are normalized, however, 29 | /// decent precision will occur as long as both values have high bits 30 | /// set. The result is not normalized. 31 | /// 32 | /// Algorithm: 33 | /// 1. Non-signed multiplication of mantissas (requires 2x as many bits as input). 34 | /// 2. Normalization of the result (not done here). 35 | /// 3. Addition of exponents. 36 | pub(crate) fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat { 37 | // Logic check, values must be decently normalized prior to multiplication. 38 | debug_assert!((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0)); 39 | 40 | // Extract high-and-low masks. 41 | let ah = self.mant >> u64::HALF; 42 | let al = self.mant & u64::LOMASK; 43 | let bh = b.mant >> u64::HALF; 44 | let bl = b.mant & u64::LOMASK; 45 | 46 | // Get our products 47 | let ah_bl = ah * bl; 48 | let al_bh = al * bh; 49 | let al_bl = al * bl; 50 | let ah_bh = ah * bh; 51 | 52 | let mut tmp = (ah_bl & u64::LOMASK) + (al_bh & u64::LOMASK) + (al_bl >> u64::HALF); 53 | // round up 54 | tmp += 1 << (u64::HALF - 1); 55 | 56 | ExtendedFloat { 57 | mant: ah_bh + (ah_bl >> u64::HALF) + (al_bh >> u64::HALF) + (tmp >> u64::HALF), 58 | exp: self.exp + b.exp + u64::FULL, 59 | } 60 | } 61 | 62 | /// Multiply in-place, as if by `a*b`. 63 | /// 64 | /// The result is not normalized. 65 | #[inline] 66 | pub(crate) fn imul(&mut self, b: &ExtendedFloat) { 67 | *self = self.mul(b); 68 | } 69 | 70 | // NORMALIZE 71 | 72 | /// Normalize float-point number. 73 | /// 74 | /// Shift the mantissa so the number of leading zeros is 0, or the value 75 | /// itself is 0. 76 | /// 77 | /// Get the number of bytes shifted. 78 | #[inline] 79 | pub(crate) fn normalize(&mut self) -> u32 { 80 | // Note: 81 | // Using the cltz intrinsic via leading_zeros is way faster (~10x) 82 | // than shifting 1-bit at a time, via while loop, and also way 83 | // faster (~2x) than an unrolled loop that checks at 32, 16, 4, 84 | // 2, and 1 bit. 85 | // 86 | // Using a modulus of pow2 (which will get optimized to a bitwise 87 | // and with 0x3F or faster) is slightly slower than an if/then, 88 | // however, removing the if/then will likely optimize more branched 89 | // code as it removes conditional logic. 90 | 91 | // Calculate the number of leading zeros, and then zero-out 92 | // any overflowing bits, to avoid shl overflow when self.mant == 0. 93 | let shift = if self.mant == 0 { 94 | 0 95 | } else { 96 | self.mant.leading_zeros() 97 | }; 98 | shl(self, shift as i32); 99 | shift 100 | } 101 | 102 | // ROUND 103 | 104 | /// Lossy round float-point number to native mantissa boundaries. 105 | #[inline] 106 | pub(crate) fn round_to_native(&mut self, algorithm: Algorithm) 107 | where 108 | F: Float, 109 | Algorithm: FnOnce(&mut ExtendedFloat, i32), 110 | { 111 | round_to_native::(self, algorithm); 112 | } 113 | 114 | // FROM 115 | 116 | /// Create extended float from native float. 117 | #[inline] 118 | pub fn from_float(f: F) -> ExtendedFloat { 119 | from_float(f) 120 | } 121 | 122 | // INTO 123 | 124 | /// Convert into default-rounded, lower-precision native float. 125 | #[inline] 126 | pub(crate) fn into_float(mut self) -> F { 127 | self.round_to_native::(round_nearest_tie_even); 128 | into_float(self) 129 | } 130 | 131 | /// Convert into downward-rounded, lower-precision native float. 132 | #[inline] 133 | pub(crate) fn into_downward_float(mut self) -> F { 134 | self.round_to_native::(round_downward); 135 | into_float(self) 136 | } 137 | } 138 | 139 | // FROM FLOAT 140 | 141 | // Import ExtendedFloat from native float. 142 | #[inline] 143 | pub(crate) fn from_float(f: F) -> ExtendedFloat 144 | where 145 | F: Float, 146 | { 147 | ExtendedFloat { 148 | mant: u64::as_cast(f.mantissa()), 149 | exp: f.exponent(), 150 | } 151 | } 152 | 153 | // INTO FLOAT 154 | 155 | // Export extended-precision float to native float. 156 | // 157 | // The extended-precision float must be in native float representation, 158 | // with overflow/underflow appropriately handled. 159 | #[inline] 160 | pub(crate) fn into_float(fp: ExtendedFloat) -> F 161 | where 162 | F: Float, 163 | { 164 | // Export floating-point number. 165 | if fp.mant == 0 || fp.exp < F::DENORMAL_EXPONENT { 166 | // sub-denormal, underflow 167 | F::ZERO 168 | } else if fp.exp >= F::MAX_EXPONENT { 169 | // overflow 170 | F::from_bits(F::INFINITY_BITS) 171 | } else { 172 | // calculate the exp and fraction bits, and return a float from bits. 173 | let exp: u64; 174 | if (fp.exp == F::DENORMAL_EXPONENT) && (fp.mant & F::HIDDEN_BIT_MASK.as_u64()) == 0 { 175 | exp = 0; 176 | } else { 177 | exp = (fp.exp + F::EXPONENT_BIAS) as u64; 178 | } 179 | let exp = exp << F::MANTISSA_SIZE; 180 | let mant = fp.mant & F::MANTISSA_MASK.as_u64(); 181 | F::from_bits(F::Unsigned::as_cast(mant | exp)) 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/lexical/large_powers.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Precalculated large powers for limbs. 4 | 5 | #[cfg(fast_arithmetic = "32")] 6 | pub(crate) use super::large_powers32::*; 7 | 8 | #[cfg(fast_arithmetic = "64")] 9 | pub(crate) use super::large_powers64::*; 10 | -------------------------------------------------------------------------------- /src/lexical/large_powers32.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Precalculated large powers for 32-bit limbs. 4 | 5 | /// Large powers (`&[u32]`) for base5 operations. 6 | const POW5_1: [u32; 1] = [5]; 7 | const POW5_2: [u32; 1] = [25]; 8 | const POW5_3: [u32; 1] = [625]; 9 | const POW5_4: [u32; 1] = [390625]; 10 | const POW5_5: [u32; 2] = [2264035265, 35]; 11 | const POW5_6: [u32; 3] = [2242703233, 762134875, 1262]; 12 | const POW5_7: [u32; 5] = [3211403009, 1849224548, 3668416493, 3913284084, 1593091]; 13 | const POW5_8: [u32; 10] = [ 14 | 781532673, 64985353, 253049085, 594863151, 3553621484, 3288652808, 3167596762, 2788392729, 15 | 3911132675, 590, 16 | ]; 17 | const POW5_9: [u32; 19] = [ 18 | 2553183233, 3201533787, 3638140786, 303378311, 1809731782, 3477761648, 3583367183, 649228654, 19 | 2915460784, 487929380, 1011012442, 1677677582, 3428152256, 1710878487, 1438394610, 2161952759, 20 | 4100910556, 1608314830, 349175, 21 | ]; 22 | const POW5_10: [u32; 38] = [ 23 | 4234999809, 2012377703, 2408924892, 1570150255, 3090844311, 3273530073, 1187251475, 2498123591, 24 | 3364452033, 1148564857, 687371067, 2854068671, 1883165473, 505794538, 2988060450, 3159489326, 25 | 2531348317, 3215191468, 849106862, 3892080979, 3288073877, 2242451748, 4183778142, 2995818208, 26 | 2477501924, 325481258, 2487842652, 1774082830, 1933815724, 2962865281, 1168579910, 2724829000, 27 | 2360374019, 2315984659, 2360052375, 3251779801, 1664357844, 28, 28 | ]; 29 | const POW5_11: [u32; 75] = [ 30 | 689565697, 4116392818, 1853628763, 516071302, 2568769159, 365238920, 336250165, 1283268122, 31 | 3425490969, 248595470, 2305176814, 2111925499, 507770399, 2681111421, 589114268, 591287751, 32 | 1708941527, 4098957707, 475844916, 3378731398, 2452339615, 2817037361, 2678008327, 1656645978, 33 | 2383430340, 73103988, 448667107, 2329420453, 3124020241, 3625235717, 3208634035, 2412059158, 34 | 2981664444, 4117622508, 838560765, 3069470027, 270153238, 1802868219, 3692709886, 2161737865, 35 | 2159912357, 2585798786, 837488486, 4237238160, 2540319504, 3798629246, 3748148874, 1021550776, 36 | 2386715342, 1973637538, 1823520457, 1146713475, 833971519, 3277251466, 905620390, 26278816, 37 | 2680483154, 2294040859, 373297482, 5996609, 4109575006, 512575049, 917036550, 1942311753, 38 | 2816916778, 3248920332, 1192784020, 3537586671, 2456567643, 2925660628, 759380297, 888447942, 39 | 3559939476, 3654687237, 805, 40 | ]; 41 | const POW5_12: [u32; 149] = [ 42 | 322166785, 3809044581, 2994556223, 1239584207, 3962455841, 4001882964, 3053876612, 915114683, 43 | 2783289745, 785739093, 4253185907, 3931164994, 1370983858, 2553556126, 3360742076, 2255410929, 44 | 422849554, 2457422215, 3539495362, 1720790602, 1908931983, 1470596141, 592794347, 4219465164, 45 | 4085652704, 941661409, 2534650953, 885063988, 2355909854, 2812815516, 767256131, 3821757683, 46 | 2155151105, 3817418473, 281116564, 2834395026, 2821201622, 2524625843, 1511330880, 2572352493, 47 | 330571332, 2951088579, 2730271766, 4044456479, 4212286644, 2444937588, 3603420843, 2387148597, 48 | 1142537539, 3299235429, 1751012624, 861228086, 2873722519, 230498814, 1023297821, 2553128038, 49 | 3421129895, 2651917435, 2042981258, 1606787143, 2228751918, 447345732, 1930371132, 1784132011, 50 | 3612538790, 2275925090, 2487567871, 1080427616, 2009179183, 3383506781, 3899054063, 1950782960, 51 | 2168622213, 2717674390, 3616636027, 2079341593, 1530129217, 1461057425, 2406264415, 3674671357, 52 | 2972036238, 2019354295, 1455849819, 1866918619, 1324269294, 424891864, 2722422332, 2641594816, 53 | 1400249021, 3482963993, 3734946379, 225889849, 1891545473, 777383150, 3589824633, 4117601611, 54 | 4220028667, 334453379, 1083130821, 1060342180, 4208163139, 1489826908, 4163762246, 1096580926, 55 | 689301528, 2336054516, 1782865703, 4175148410, 3398369392, 2329412588, 3001580596, 59740741, 56 | 3202189932, 3351895776, 246185302, 718535188, 3772647488, 4151666556, 4055698133, 2461934110, 57 | 2281316281, 3466396836, 3536023465, 1064267812, 2955456354, 2423805422, 3627960790, 1325057500, 58 | 3876919979, 2009959531, 175455101, 184092852, 2358785571, 3842977831, 2485266289, 487121622, 59 | 4159252710, 4075707558, 459389244, 300652075, 2521346588, 3458976673, 888631636, 2076098096, 60 | 3844514585, 2363697580, 3729421522, 3051115477, 649395, 61 | ]; 62 | const POW5_13: [u32; 298] = [ 63 | 711442433, 3564261005, 2399042279, 4170849936, 4010295575, 1423987028, 330414929, 1349249065, 64 | 4213813618, 3852031822, 4040843590, 2154565331, 3094013374, 1159028371, 3227065538, 2115927092, 65 | 2085102554, 488590542, 2609619432, 3602898805, 3812736528, 3269439096, 23816114, 253984538, 66 | 1035905997, 2942969204, 3400787671, 338562688, 1637191975, 740509713, 2264962817, 3410753922, 67 | 4162231428, 2282041228, 1759373012, 3155367777, 4278913285, 1420532801, 1981002276, 438054990, 68 | 1006507643, 1142697287, 1332538012, 2029019521, 3949305784, 818392641, 2491288846, 2716584663, 69 | 3648886102, 556814413, 444795339, 4071412999, 1066321706, 4253169466, 2510832316, 672091442, 70 | 4083256000, 2165985028, 1841538484, 3549854235, 364431512, 3707648143, 1162785440, 2268641545, 71 | 281340310, 735693841, 848809228, 1700785200, 2919703985, 4094234344, 58530286, 965505005, 72 | 1000010347, 3381961808, 3040089923, 1973852082, 2890971585, 1019960210, 4292895237, 2821887841, 73 | 3756675650, 3951282907, 3885870583, 1008791145, 503998487, 1881258362, 1949332730, 392996726, 74 | 2012973814, 3970014187, 2461725150, 2942547730, 3728066699, 2766901132, 3778532841, 1085564064, 75 | 2278673896, 1116879805, 3448726271, 774279411, 157211670, 1506320155, 531168605, 1362654525, 76 | 956967721, 2148871960, 769186085, 4186232894, 2055679604, 3248365487, 3981268013, 3975787984, 77 | 2489510517, 3309046495, 212771124, 933418041, 3371839114, 562115198, 1853601831, 757336096, 78 | 1354633440, 1486083256, 2872126393, 522920738, 1141587749, 3210903262, 1926940553, 3054024853, 79 | 2021162538, 2262742000, 1877899947, 3147002868, 669840763, 4158174590, 4238502559, 1023731922, 80 | 3386840011, 829588074, 3449720188, 2835142880, 2999162007, 813056473, 482949569, 638108879, 81 | 3067201471, 1026714238, 4004452838, 2383667807, 3999477803, 771648919, 630660440, 3827121348, 82 | 176185980, 2878191002, 2666149832, 3909811063, 2429163983, 2665690412, 907266128, 4269332098, 83 | 2022665808, 1527122180, 3072053668, 1072477492, 3006022924, 549664855, 2800340954, 37352654, 84 | 1212772743, 2711280533, 3029527946, 2511120040, 1305308377, 3474662224, 4226330922, 442988428, 85 | 954940108, 3274548099, 4212288177, 2688499880, 3982226758, 3922609956, 1279948029, 1939943640, 86 | 3650489901, 2733364929, 2494263275, 1864579964, 1225941120, 2390465139, 1267503249, 3533240729, 87 | 904410805, 2842550015, 2517736241, 1796069820, 3335274381, 673539835, 1924694759, 3598098235, 88 | 2792633405, 16535707, 3703535497, 3592841791, 2929082877, 1317622811, 294990855, 1396706563, 89 | 2383271770, 3853857605, 277813677, 277580220, 1101318484, 3761974115, 1132150143, 2544692622, 90 | 3419825776, 743770306, 1695464553, 1548693232, 2421159615, 2575672031, 2678971806, 1591267897, 91 | 626546738, 3823443129, 267710932, 1455435162, 2353985540, 3248523795, 335348168, 3872552561, 92 | 2814522612, 2634118860, 3503767026, 1301019273, 1414467789, 722985138, 3070909565, 4253482569, 93 | 3744939841, 558142907, 2229819389, 13833173, 77003966, 2763671364, 3905603970, 2931990126, 94 | 2280419384, 1879090457, 2934846267, 4284933164, 2331863845, 62191163, 3178861020, 1522063815, 95 | 785672270, 1215568492, 2936443917, 802972489, 2956820173, 3916732783, 2893572089, 1391232801, 96 | 3168640330, 2396859648, 894950918, 1103583736, 961991865, 2807302642, 305977505, 3054505899, 97 | 1048256994, 781017659, 2459278754, 3164823415, 537658277, 905753687, 464963300, 4149131560, 98 | 1029507924, 2278300961, 1231291503, 414073408, 3630740085, 2345841814, 475358196, 3258243317, 99 | 4167625072, 4178911231, 2927355042, 655438830, 3138378018, 623200562, 2785714112, 273403236, 100 | 807993669, 98, 101 | ]; 102 | const POW5_14: [u32; 595] = [ 103 | 1691320321, 2671006246, 1682531301, 2072858707, 1240508969, 3108358191, 1125119096, 2470144952, 104 | 1610099978, 1690632660, 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936, 105 | 4078768933, 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313, 106 | 1254424514, 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749, 107 | 2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861, 125491448, 108 | 1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701, 483795093, 109 | 1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571, 1094885097, 4223064276, 110 | 3307819021, 651121777, 1757003305, 3603542336, 129917786, 2215974994, 3042386306, 2205352757, 111 | 3944939700, 3710987569, 97967515, 1217242524, 930630949, 3660328512, 1787663098, 1784141600, 112 | 2500542892, 4034561586, 3444961378, 785043562, 3869499367, 885623728, 2625011087, 3053789617, 113 | 1965731793, 3900511934, 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160, 114 | 1348009103, 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552, 115 | 2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748, 1739996642, 116 | 1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406, 785287846, 1671499798, 117 | 433044045, 1919608025, 264833858, 3999983367, 1116778570, 1301982149, 4213901070, 4081649357, 118 | 536169226, 1389008649, 188923873, 373495152, 2551132278, 1800758715, 3951840330, 2632334454, 119 | 3118778225, 1034046547, 1862428410, 3037609062, 1994608505, 29051798, 2571685694, 264151332, 120 | 2260643090, 2717535964, 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570, 121 | 3676533911, 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173, 122 | 1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527, 2507669891, 123 | 2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954, 2204775591, 1037094060, 124 | 829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123, 488286513, 50685385, 125 | 3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248, 3708476086, 10375249, 126 | 4172112346, 2117510871, 2227658327, 3187664554, 3050656558, 328034318, 3179601324, 1247769761, 127 | 3439263953, 1431538938, 2962525068, 1213366289, 3813013550, 2651093719, 1860661503, 3933716208, 128 | 264320617, 789980519, 2257856172, 102000748, 977269860, 1113845122, 3008928583, 1461738106, 129 | 557786285, 2926560363, 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056, 130 | 2076808229, 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232, 131 | 2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742, 132 | 3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881, 3227511198, 133 | 2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386, 584244184, 1450926016, 134 | 2462430443, 3226534010, 298582169, 4214576928, 1762099469, 964985185, 1585788148, 1641127666, 135 | 787006566, 2315956284, 3258232694, 2275058964, 2541003317, 1508235863, 2613339827, 4080647514, 136 | 1152057965, 3149266279, 731345410, 914737650, 65395712, 1884566942, 1379520432, 2611027720, 137 | 4163073378, 2619704967, 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279, 138 | 4051522914, 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776, 139 | 253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225, 140 | 2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199, 292769859, 141 | 2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636, 3540280538, 2982120874, 142 | 2136414455, 255762046, 3852783591, 3262064164, 2358991588, 3756586117, 4143612643, 3326743817, 143 | 2897365738, 807711264, 3719310016, 3721264861, 3627337076, 944539331, 3640975513, 3712525681, 144 | 1162911839, 2008243316, 2179489649, 2867584109, 261861553, 3570253908, 2062868357, 2220328623, 145 | 3857004679, 3744109002, 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584, 146 | 1223182946, 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643, 147 | 400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761, 148 | 3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362, 3454286017, 149 | 2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345, 1381875722, 1661526119, 150 | 1082778324, 3571910052, 1140625929, 851544870, 1145546234, 2938573139, 907528924, 1304752338, 151 | 1764668294, 1788942063, 1700368828, 104979467, 1413911959, 3327497828, 1956384744, 1272712474, 152 | 2815637534, 3307809377, 1320574940, 1111968962, 4073107827, 434096622, 169451929, 3201183459, 153 | 3331028877, 2852366972, 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722, 154 | 2721281595, 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708, 155 | 992340967, 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683, 156 | 1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270, 173719711, 157 | 3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998, 3573073830, 158 | 841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278, 3964109906, 677238797, 159 | 537994297, 1124184993, 4287078344, 4207654540, 2943022776, 2977947524, 3255359985, 4098397558, 160 | 2274666217, 2915862060, 243524940, 2467726756, 2869020032, 507521339, 3403121914, 522051455, 161 | 1803903108, 3471254194, 473535371, 1948602036, 3352095732, 3116527002, 1795743673, 775867940, 162 | 2551469548, 3757442064, 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130, 163 | 1342349989, 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609, 164 | 1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726, 2821790499, 165 | 2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345, 378322447, 156541411, 166 | 1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024, 4166396241, 509467541, 167 | 2906024136, 1221753746, 3375413222, 431327897, 2749265123, 2848827671, 3412997614, 2051920238, 168 | 1283516885, 1300498239, 1957256104, 2634010560, 3531900395, 360276850, 1461184973, 2012063967, 169 | 2873572430, 2914608609, 4289554777, 1539331673, 1859532928, 4213441063, 538215691, 3512720863, 170 | 4258743698, 3040408445, 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460, 171 | 2864275059, 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456, 172 | 2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775, 3887426070, 173 | 3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114, 1596072055, 1928415752, 174 | 3635452689, 1005598891, 3335462724, 3290848636, 3669078247, 1178176812, 2110774376, 3068593619, 175 | 1253036518, 908857731, 3631223047, 4138506423, 2903592318, 3596915748, 3289036113, 3721512676, 176 | 2704409359, 3386016968, 3676268074, 2185259502, 1096257611, 3360076717, 3548676554, 170167319, 177 | 3360064287, 3899940843, 9640, 178 | ]; 179 | 180 | pub(crate) const POW5: [&'static [u32]; 14] = [ 181 | &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10, 182 | &POW5_11, &POW5_12, &POW5_13, &POW5_14, 183 | ]; 184 | -------------------------------------------------------------------------------- /src/lexical/mod.rs: -------------------------------------------------------------------------------- 1 | // The code in this module is derived from the `lexical` crate by @Alexhuszagh 2 | // which the author condensed into this minimal subset for use in serde_json. 3 | // For the serde_json use case we care more about reliably round tripping all 4 | // possible floating point values than about parsing any arbitrarily long string 5 | // of digits with perfect accuracy, as the latter would take a high cost in 6 | // compile time and performance. 7 | // 8 | // Dual licensed as MIT and Apache 2.0 just like the rest of serde_json, but 9 | // copyright Alexander Huszagh. 10 | 11 | //! Fast, minimal float-parsing algorithm. 12 | 13 | // MODULES 14 | pub(crate) mod algorithm; 15 | mod bhcomp; 16 | mod bignum; 17 | mod cached; 18 | mod cached_float80; 19 | mod digit; 20 | mod errors; 21 | pub(crate) mod exponent; 22 | pub(crate) mod float; 23 | mod large_powers; 24 | pub(crate) mod math; 25 | pub(crate) mod num; 26 | pub(crate) mod parse; 27 | pub(crate) mod rounding; 28 | mod shift; 29 | mod small_powers; 30 | 31 | #[cfg(fast_arithmetic = "32")] 32 | mod large_powers32; 33 | 34 | #[cfg(fast_arithmetic = "64")] 35 | mod large_powers64; 36 | 37 | // API 38 | pub use self::parse::{parse_concise_float, parse_truncated_float}; 39 | -------------------------------------------------------------------------------- /src/lexical/num.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Utilities for Rust numbers. 4 | 5 | use core::ops; 6 | 7 | /// Precalculated values of radix**i for i in range [0, arr.len()-1]. 8 | /// Each value can be **exactly** represented as that type. 9 | const F32_POW10: [f32; 11] = [ 10 | 1.0, 11 | 10.0, 12 | 100.0, 13 | 1000.0, 14 | 10000.0, 15 | 100000.0, 16 | 1000000.0, 17 | 10000000.0, 18 | 100000000.0, 19 | 1000000000.0, 20 | 10000000000.0, 21 | ]; 22 | 23 | /// Precalculated values of radix**i for i in range [0, arr.len()-1]. 24 | /// Each value can be **exactly** represented as that type. 25 | const F64_POW10: [f64; 23] = [ 26 | 1.0, 27 | 10.0, 28 | 100.0, 29 | 1000.0, 30 | 10000.0, 31 | 100000.0, 32 | 1000000.0, 33 | 10000000.0, 34 | 100000000.0, 35 | 1000000000.0, 36 | 10000000000.0, 37 | 100000000000.0, 38 | 1000000000000.0, 39 | 10000000000000.0, 40 | 100000000000000.0, 41 | 1000000000000000.0, 42 | 10000000000000000.0, 43 | 100000000000000000.0, 44 | 1000000000000000000.0, 45 | 10000000000000000000.0, 46 | 100000000000000000000.0, 47 | 1000000000000000000000.0, 48 | 10000000000000000000000.0, 49 | ]; 50 | 51 | /// Type that can be converted to primitive with `as`. 52 | pub trait AsPrimitive: Sized + Copy + PartialOrd { 53 | fn as_u32(self) -> u32; 54 | fn as_u64(self) -> u64; 55 | fn as_u128(self) -> u128; 56 | fn as_usize(self) -> usize; 57 | fn as_f32(self) -> f32; 58 | fn as_f64(self) -> f64; 59 | } 60 | 61 | macro_rules! as_primitive_impl { 62 | ($($ty:ident)*) => { 63 | $( 64 | impl AsPrimitive for $ty { 65 | #[inline] 66 | fn as_u32(self) -> u32 { 67 | self as u32 68 | } 69 | 70 | #[inline] 71 | fn as_u64(self) -> u64 { 72 | self as u64 73 | } 74 | 75 | #[inline] 76 | fn as_u128(self) -> u128 { 77 | self as u128 78 | } 79 | 80 | #[inline] 81 | fn as_usize(self) -> usize { 82 | self as usize 83 | } 84 | 85 | #[inline] 86 | fn as_f32(self) -> f32 { 87 | self as f32 88 | } 89 | 90 | #[inline] 91 | fn as_f64(self) -> f64 { 92 | self as f64 93 | } 94 | } 95 | )* 96 | }; 97 | } 98 | 99 | as_primitive_impl! { u32 u64 u128 usize f32 f64 } 100 | 101 | /// An interface for casting between machine scalars. 102 | pub trait AsCast: AsPrimitive { 103 | /// Creates a number from another value that can be converted into 104 | /// a primitive via the `AsPrimitive` trait. 105 | fn as_cast(n: N) -> Self; 106 | } 107 | 108 | macro_rules! as_cast_impl { 109 | ($ty:ident, $method:ident) => { 110 | impl AsCast for $ty { 111 | #[inline] 112 | fn as_cast(n: N) -> Self { 113 | n.$method() 114 | } 115 | } 116 | }; 117 | } 118 | 119 | as_cast_impl!(u32, as_u32); 120 | as_cast_impl!(u64, as_u64); 121 | as_cast_impl!(u128, as_u128); 122 | as_cast_impl!(usize, as_usize); 123 | as_cast_impl!(f32, as_f32); 124 | as_cast_impl!(f64, as_f64); 125 | 126 | /// Numerical type trait. 127 | pub trait Number: AsCast + ops::Add {} 128 | 129 | macro_rules! number_impl { 130 | ($($ty:ident)*) => { 131 | $( 132 | impl Number for $ty {} 133 | )* 134 | }; 135 | } 136 | 137 | number_impl! { u32 u64 u128 usize f32 f64 } 138 | 139 | /// Defines a trait that supports integral operations. 140 | pub trait Integer: Number + ops::BitAnd + ops::Shr { 141 | const ZERO: Self; 142 | } 143 | 144 | macro_rules! integer_impl { 145 | ($($ty:tt)*) => { 146 | $( 147 | impl Integer for $ty { 148 | const ZERO: Self = 0; 149 | } 150 | )* 151 | }; 152 | } 153 | 154 | integer_impl! { u32 u64 u128 usize } 155 | 156 | /// Type trait for the mantissa type. 157 | pub trait Mantissa: Integer { 158 | /// Mask to extract the high bits from the integer. 159 | const HIMASK: Self; 160 | /// Mask to extract the low bits from the integer. 161 | const LOMASK: Self; 162 | /// Full size of the integer, in bits. 163 | const FULL: i32; 164 | /// Half size of the integer, in bits. 165 | const HALF: i32 = Self::FULL / 2; 166 | } 167 | 168 | impl Mantissa for u64 { 169 | const HIMASK: u64 = 0xFFFFFFFF00000000; 170 | const LOMASK: u64 = 0x00000000FFFFFFFF; 171 | const FULL: i32 = 64; 172 | } 173 | 174 | /// Get exact exponent limit for radix. 175 | pub trait Float: Number { 176 | /// Unsigned type of the same size. 177 | type Unsigned: Integer; 178 | 179 | /// Literal zero. 180 | const ZERO: Self; 181 | /// Maximum number of digits that can contribute in the mantissa. 182 | /// 183 | /// We can exactly represent a float in radix `b` from radix 2 if 184 | /// `b` is divisible by 2. This function calculates the exact number of 185 | /// digits required to exactly represent that float. 186 | /// 187 | /// According to the "Handbook of Floating Point Arithmetic", 188 | /// for IEEE754, with emin being the min exponent, p2 being the 189 | /// precision, and b being the radix, the number of digits follows as: 190 | /// 191 | /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋` 192 | /// 193 | /// For f32, this follows as: 194 | /// emin = -126 195 | /// p2 = 24 196 | /// 197 | /// For f64, this follows as: 198 | /// emin = -1022 199 | /// p2 = 53 200 | /// 201 | /// In Python: 202 | /// `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))` 203 | /// 204 | /// This was used to calculate the maximum number of digits for [2, 36]. 205 | const MAX_DIGITS: usize; 206 | 207 | // MASKS 208 | 209 | /// Bitmask for the exponent, including the hidden bit. 210 | const EXPONENT_MASK: Self::Unsigned; 211 | /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction. 212 | const HIDDEN_BIT_MASK: Self::Unsigned; 213 | /// Bitmask for the mantissa (fraction), excluding the hidden bit. 214 | const MANTISSA_MASK: Self::Unsigned; 215 | 216 | // PROPERTIES 217 | 218 | /// Positive infinity as bits. 219 | const INFINITY_BITS: Self::Unsigned; 220 | /// Size of the significand (mantissa) without hidden bit. 221 | const MANTISSA_SIZE: i32; 222 | /// Bias of the exponent 223 | const EXPONENT_BIAS: i32; 224 | /// Exponent portion of a denormal float. 225 | const DENORMAL_EXPONENT: i32; 226 | /// Maximum exponent value in float. 227 | const MAX_EXPONENT: i32; 228 | 229 | // ROUNDING 230 | 231 | /// Default number of bits to shift (or 64 - mantissa size - 1). 232 | const DEFAULT_SHIFT: i32; 233 | /// Mask to determine if a full-carry occurred (1 in bit above hidden bit). 234 | const CARRY_MASK: u64; 235 | 236 | /// Get min and max exponent limits (exact) from radix. 237 | fn exponent_limit() -> (i32, i32); 238 | 239 | /// Get the number of digits that can be shifted from exponent to mantissa. 240 | fn mantissa_limit() -> i32; 241 | 242 | // Re-exported methods from std. 243 | fn pow10(self, n: i32) -> Self; 244 | fn from_bits(u: Self::Unsigned) -> Self; 245 | fn to_bits(self) -> Self::Unsigned; 246 | fn is_sign_positive(self) -> bool; 247 | 248 | /// Returns true if the float is a denormal. 249 | #[inline] 250 | fn is_denormal(self) -> bool { 251 | self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO 252 | } 253 | 254 | /// Returns true if the float is a NaN or Infinite. 255 | #[inline] 256 | fn is_special(self) -> bool { 257 | self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK 258 | } 259 | 260 | /// Returns true if the float is infinite. 261 | #[inline] 262 | fn is_inf(self) -> bool { 263 | self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO 264 | } 265 | 266 | /// Get exponent component from the float. 267 | #[inline] 268 | fn exponent(self) -> i32 { 269 | if self.is_denormal() { 270 | return Self::DENORMAL_EXPONENT; 271 | } 272 | 273 | let bits = self.to_bits(); 274 | let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32(); 275 | biased_e as i32 - Self::EXPONENT_BIAS 276 | } 277 | 278 | /// Get mantissa (significand) component from float. 279 | #[inline] 280 | fn mantissa(self) -> Self::Unsigned { 281 | let bits = self.to_bits(); 282 | let s = bits & Self::MANTISSA_MASK; 283 | if !self.is_denormal() { 284 | s + Self::HIDDEN_BIT_MASK 285 | } else { 286 | s 287 | } 288 | } 289 | 290 | /// Get next greater float for a positive float. 291 | /// Value must be >= 0.0 and < INFINITY. 292 | #[inline] 293 | fn next_positive(self) -> Self { 294 | debug_assert!(self.is_sign_positive() && !self.is_inf()); 295 | Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32)) 296 | } 297 | 298 | /// Round a positive number to even. 299 | #[inline] 300 | fn round_positive_even(self) -> Self { 301 | if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) { 302 | self.next_positive() 303 | } else { 304 | self 305 | } 306 | } 307 | } 308 | 309 | impl Float for f32 { 310 | type Unsigned = u32; 311 | 312 | const ZERO: f32 = 0.0; 313 | const MAX_DIGITS: usize = 114; 314 | const EXPONENT_MASK: u32 = 0x7F800000; 315 | const HIDDEN_BIT_MASK: u32 = 0x00800000; 316 | const MANTISSA_MASK: u32 = 0x007FFFFF; 317 | const INFINITY_BITS: u32 = 0x7F800000; 318 | const MANTISSA_SIZE: i32 = 23; 319 | const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE; 320 | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; 321 | const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS; 322 | const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1; 323 | const CARRY_MASK: u64 = 0x1000000; 324 | 325 | #[inline] 326 | fn exponent_limit() -> (i32, i32) { 327 | (-10, 10) 328 | } 329 | 330 | #[inline] 331 | fn mantissa_limit() -> i32 { 332 | 7 333 | } 334 | 335 | #[inline] 336 | fn pow10(self, n: i32) -> f32 { 337 | // Check the exponent is within bounds in debug builds. 338 | debug_assert!({ 339 | let (min, max) = Self::exponent_limit(); 340 | n >= min && n <= max 341 | }); 342 | 343 | if n > 0 { 344 | self * F32_POW10[n as usize] 345 | } else { 346 | self / F32_POW10[-n as usize] 347 | } 348 | } 349 | 350 | #[inline] 351 | fn from_bits(u: u32) -> f32 { 352 | f32::from_bits(u) 353 | } 354 | 355 | #[inline] 356 | fn to_bits(self) -> u32 { 357 | f32::to_bits(self) 358 | } 359 | 360 | #[inline] 361 | fn is_sign_positive(self) -> bool { 362 | f32::is_sign_positive(self) 363 | } 364 | } 365 | 366 | impl Float for f64 { 367 | type Unsigned = u64; 368 | 369 | const ZERO: f64 = 0.0; 370 | const MAX_DIGITS: usize = 769; 371 | const EXPONENT_MASK: u64 = 0x7FF0000000000000; 372 | const HIDDEN_BIT_MASK: u64 = 0x0010000000000000; 373 | const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF; 374 | const INFINITY_BITS: u64 = 0x7FF0000000000000; 375 | const MANTISSA_SIZE: i32 = 52; 376 | const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE; 377 | const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS; 378 | const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS; 379 | const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1; 380 | const CARRY_MASK: u64 = 0x20000000000000; 381 | 382 | #[inline] 383 | fn exponent_limit() -> (i32, i32) { 384 | (-22, 22) 385 | } 386 | 387 | #[inline] 388 | fn mantissa_limit() -> i32 { 389 | 15 390 | } 391 | 392 | #[inline] 393 | fn pow10(self, n: i32) -> f64 { 394 | // Check the exponent is within bounds in debug builds. 395 | debug_assert!({ 396 | let (min, max) = Self::exponent_limit(); 397 | n >= min && n <= max 398 | }); 399 | 400 | if n > 0 { 401 | self * F64_POW10[n as usize] 402 | } else { 403 | self / F64_POW10[-n as usize] 404 | } 405 | } 406 | 407 | #[inline] 408 | fn from_bits(u: u64) -> f64 { 409 | f64::from_bits(u) 410 | } 411 | 412 | #[inline] 413 | fn to_bits(self) -> u64 { 414 | f64::to_bits(self) 415 | } 416 | 417 | #[inline] 418 | fn is_sign_positive(self) -> bool { 419 | f64::is_sign_positive(self) 420 | } 421 | } 422 | -------------------------------------------------------------------------------- /src/lexical/parse.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use super::algorithm::*; 4 | use super::bhcomp::*; 5 | use super::digit::*; 6 | use super::exponent::*; 7 | use super::num::*; 8 | 9 | // PARSERS 10 | // ------- 11 | 12 | /// Parse float for which the entire integer and fraction parts fit into a 64 13 | /// bit mantissa. 14 | pub fn parse_concise_float(mantissa: u64, mant_exp: i32) -> F 15 | where 16 | F: Float, 17 | { 18 | if let Some(float) = fast_path(mantissa, mant_exp) { 19 | return float; 20 | } 21 | 22 | // Moderate path (use an extended 80-bit representation). 23 | let truncated = false; 24 | let (fp, valid) = moderate_path::(mantissa, mant_exp, truncated); 25 | if valid { 26 | return fp.into_float::(); 27 | } 28 | 29 | let b = fp.into_downward_float::(); 30 | if b.is_special() { 31 | // We have a non-finite number, we get to leave early. 32 | return b; 33 | } 34 | 35 | // Slow path, fast path didn't work. 36 | let mut buffer = itoa::Buffer::new(); 37 | let integer = buffer.format(mantissa).as_bytes(); 38 | let fraction = &[]; 39 | bhcomp(b, integer, fraction, mant_exp) 40 | } 41 | 42 | /// Parse float from extracted float components. 43 | /// 44 | /// * `integer` - Slice containing the integer digits. 45 | /// * `fraction` - Slice containing the fraction digits. 46 | /// * `exponent` - Parsed, 32-bit exponent. 47 | /// 48 | /// Precondition: The integer must not have leading zeros. 49 | pub fn parse_truncated_float(integer: &[u8], mut fraction: &[u8], exponent: i32) -> F 50 | where 51 | F: Float, 52 | { 53 | // Trim trailing zeroes from the fraction part. 54 | while fraction.last() == Some(&b'0') { 55 | fraction = &fraction[..fraction.len() - 1]; 56 | } 57 | 58 | // Calculate the number of truncated digits. 59 | let mut truncated = 0; 60 | let mut mantissa: u64 = 0; 61 | let mut iter = integer.iter().chain(fraction); 62 | for &c in &mut iter { 63 | mantissa = match add_digit(mantissa, to_digit(c).unwrap()) { 64 | Some(v) => v, 65 | None => { 66 | truncated = 1 + iter.count(); 67 | break; 68 | } 69 | }; 70 | } 71 | 72 | let mant_exp = mantissa_exponent(exponent, fraction.len(), truncated); 73 | let is_truncated = true; 74 | 75 | fallback_path( 76 | integer, 77 | fraction, 78 | mantissa, 79 | exponent, 80 | mant_exp, 81 | is_truncated, 82 | ) 83 | } 84 | -------------------------------------------------------------------------------- /src/lexical/rounding.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Defines rounding schemes for floating-point numbers. 4 | 5 | use super::float::ExtendedFloat; 6 | use super::num::*; 7 | use super::shift::*; 8 | use core::mem; 9 | 10 | // MASKS 11 | 12 | /// Calculate a scalar factor of 2 above the halfway point. 13 | #[inline] 14 | pub(crate) fn nth_bit(n: u64) -> u64 { 15 | let bits: u64 = mem::size_of::() as u64 * 8; 16 | debug_assert!(n < bits, "nth_bit() overflow in shl."); 17 | 18 | 1 << n 19 | } 20 | 21 | /// Generate a bitwise mask for the lower `n` bits. 22 | #[inline] 23 | pub(crate) fn lower_n_mask(n: u64) -> u64 { 24 | let bits: u64 = mem::size_of::() as u64 * 8; 25 | debug_assert!(n <= bits, "lower_n_mask() overflow in shl."); 26 | 27 | if n == bits { 28 | u64::MAX 29 | } else { 30 | (1 << n) - 1 31 | } 32 | } 33 | 34 | /// Calculate the halfway point for the lower `n` bits. 35 | #[inline] 36 | pub(crate) fn lower_n_halfway(n: u64) -> u64 { 37 | let bits: u64 = mem::size_of::() as u64 * 8; 38 | debug_assert!(n <= bits, "lower_n_halfway() overflow in shl."); 39 | 40 | if n == 0 { 41 | 0 42 | } else { 43 | nth_bit(n - 1) 44 | } 45 | } 46 | 47 | /// Calculate a bitwise mask with `n` 1 bits starting at the `bit` position. 48 | #[inline] 49 | pub(crate) fn internal_n_mask(bit: u64, n: u64) -> u64 { 50 | let bits: u64 = mem::size_of::() as u64 * 8; 51 | debug_assert!(bit <= bits, "internal_n_halfway() overflow in shl."); 52 | debug_assert!(n <= bits, "internal_n_halfway() overflow in shl."); 53 | debug_assert!(bit >= n, "internal_n_halfway() overflow in sub."); 54 | 55 | lower_n_mask(bit) ^ lower_n_mask(bit - n) 56 | } 57 | 58 | // NEAREST ROUNDING 59 | 60 | // Shift right N-bytes and round to the nearest. 61 | // 62 | // Return if we are above halfway and if we are halfway. 63 | #[inline] 64 | pub(crate) fn round_nearest(fp: &mut ExtendedFloat, shift: i32) -> (bool, bool) { 65 | // Extract the truncated bits using mask. 66 | // Calculate if the value of the truncated bits are either above 67 | // the mid-way point, or equal to it. 68 | // 69 | // For example, for 4 truncated bytes, the mask would be b1111 70 | // and the midway point would be b1000. 71 | let mask: u64 = lower_n_mask(shift as u64); 72 | let halfway: u64 = lower_n_halfway(shift as u64); 73 | 74 | let truncated_bits = fp.mant & mask; 75 | let is_above = truncated_bits > halfway; 76 | let is_halfway = truncated_bits == halfway; 77 | 78 | // Bit shift so the leading bit is in the hidden bit. 79 | overflowing_shr(fp, shift); 80 | 81 | (is_above, is_halfway) 82 | } 83 | 84 | // Tie rounded floating point to event. 85 | #[inline] 86 | pub(crate) fn tie_even(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) { 87 | // Extract the last bit after shifting (and determine if it is odd). 88 | let is_odd = fp.mant & 1 == 1; 89 | 90 | // Calculate if we need to roundup. 91 | // We need to roundup if we are above halfway, or if we are odd 92 | // and at half-way (need to tie-to-even). 93 | if is_above || (is_odd && is_halfway) { 94 | fp.mant += 1; 95 | } 96 | } 97 | 98 | // Shift right N-bytes and round nearest, tie-to-even. 99 | // 100 | // Floating-point arithmetic uses round to nearest, ties to even, 101 | // which rounds to the nearest value, if the value is halfway in between, 102 | // round to an even value. 103 | #[inline] 104 | pub(crate) fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32) { 105 | let (is_above, is_halfway) = round_nearest(fp, shift); 106 | tie_even(fp, is_above, is_halfway); 107 | } 108 | 109 | // DIRECTED ROUNDING 110 | 111 | // Shift right N-bytes and round towards a direction. 112 | // 113 | // Return if we have any truncated bytes. 114 | #[inline] 115 | fn round_toward(fp: &mut ExtendedFloat, shift: i32) -> bool { 116 | let mask: u64 = lower_n_mask(shift as u64); 117 | let truncated_bits = fp.mant & mask; 118 | 119 | // Bit shift so the leading bit is in the hidden bit. 120 | overflowing_shr(fp, shift); 121 | 122 | truncated_bits != 0 123 | } 124 | 125 | // Round down. 126 | #[inline] 127 | fn downard(_: &mut ExtendedFloat, _: bool) {} 128 | 129 | // Shift right N-bytes and round toward zero. 130 | // 131 | // Floating-point arithmetic defines round toward zero, which rounds 132 | // towards positive zero. 133 | #[inline] 134 | pub(crate) fn round_downward(fp: &mut ExtendedFloat, shift: i32) { 135 | // Bit shift so the leading bit is in the hidden bit. 136 | // No rounding schemes, so we just ignore everything else. 137 | let is_truncated = round_toward(fp, shift); 138 | downard(fp, is_truncated); 139 | } 140 | 141 | // ROUND TO FLOAT 142 | 143 | // Shift the ExtendedFloat fraction to the fraction bits in a native float. 144 | // 145 | // Floating-point arithmetic uses round to nearest, ties to even, 146 | // which rounds to the nearest value, if the value is halfway in between, 147 | // round to an even value. 148 | #[inline] 149 | pub(crate) fn round_to_float(fp: &mut ExtendedFloat, algorithm: Algorithm) 150 | where 151 | F: Float, 152 | Algorithm: FnOnce(&mut ExtendedFloat, i32), 153 | { 154 | // Calculate the difference to allow a single calculation 155 | // rather than a loop, to minimize the number of ops required. 156 | // This does underflow detection. 157 | let final_exp = fp.exp + F::DEFAULT_SHIFT; 158 | if final_exp < F::DENORMAL_EXPONENT { 159 | // We would end up with a denormal exponent, try to round to more 160 | // digits. Only shift right if we can avoid zeroing out the value, 161 | // which requires the exponent diff to be < M::BITS. The value 162 | // is already normalized, so we shouldn't have any issue zeroing 163 | // out the value. 164 | let diff = F::DENORMAL_EXPONENT - fp.exp; 165 | if diff <= u64::FULL { 166 | // We can avoid underflow, can get a valid representation. 167 | algorithm(fp, diff); 168 | } else { 169 | // Certain underflow, assign literal 0s. 170 | fp.mant = 0; 171 | fp.exp = 0; 172 | } 173 | } else { 174 | algorithm(fp, F::DEFAULT_SHIFT); 175 | } 176 | 177 | if fp.mant & F::CARRY_MASK == F::CARRY_MASK { 178 | // Roundup carried over to 1 past the hidden bit. 179 | shr(fp, 1); 180 | } 181 | } 182 | 183 | // AVOID OVERFLOW/UNDERFLOW 184 | 185 | // Avoid overflow for large values, shift left as needed. 186 | // 187 | // Shift until a 1-bit is in the hidden bit, if the mantissa is not 0. 188 | #[inline] 189 | pub(crate) fn avoid_overflow(fp: &mut ExtendedFloat) 190 | where 191 | F: Float, 192 | { 193 | // Calculate the difference to allow a single calculation 194 | // rather than a loop, minimizing the number of ops required. 195 | if fp.exp >= F::MAX_EXPONENT { 196 | let diff = fp.exp - F::MAX_EXPONENT; 197 | if diff <= F::MANTISSA_SIZE { 198 | // Our overflow mask needs to start at the hidden bit, or at 199 | // `F::MANTISSA_SIZE+1`, and needs to have `diff+1` bits set, 200 | // to see if our value overflows. 201 | let bit = (F::MANTISSA_SIZE + 1) as u64; 202 | let n = (diff + 1) as u64; 203 | let mask = internal_n_mask(bit, n); 204 | if (fp.mant & mask) == 0 { 205 | // If we have no 1-bit in the hidden-bit position, 206 | // which is index 0, we need to shift 1. 207 | let shift = diff + 1; 208 | shl(fp, shift); 209 | } 210 | } 211 | } 212 | } 213 | 214 | // ROUND TO NATIVE 215 | 216 | // Round an extended-precision float to a native float representation. 217 | #[inline] 218 | pub(crate) fn round_to_native(fp: &mut ExtendedFloat, algorithm: Algorithm) 219 | where 220 | F: Float, 221 | Algorithm: FnOnce(&mut ExtendedFloat, i32), 222 | { 223 | // Shift all the way left, to ensure a consistent representation. 224 | // The following right-shifts do not work for a non-normalized number. 225 | fp.normalize(); 226 | 227 | // Round so the fraction is in a native mantissa representation, 228 | // and avoid overflow/underflow. 229 | round_to_float::(fp, algorithm); 230 | avoid_overflow::(fp); 231 | } 232 | -------------------------------------------------------------------------------- /src/lexical/shift.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Bit-shift helpers. 4 | 5 | use super::float::ExtendedFloat; 6 | use core::mem; 7 | 8 | // Shift extended-precision float right `shift` bytes. 9 | #[inline] 10 | pub(crate) fn shr(fp: &mut ExtendedFloat, shift: i32) { 11 | let bits: u64 = mem::size_of::() as u64 * 8; 12 | debug_assert!((shift as u64) < bits, "shr() overflow in shift right."); 13 | 14 | fp.mant >>= shift; 15 | fp.exp += shift; 16 | } 17 | 18 | // Shift extended-precision float right `shift` bytes. 19 | // 20 | // Accepts when the shift is the same as the type size, and 21 | // sets the value to 0. 22 | #[inline] 23 | pub(crate) fn overflowing_shr(fp: &mut ExtendedFloat, shift: i32) { 24 | let bits: u64 = mem::size_of::() as u64 * 8; 25 | debug_assert!( 26 | (shift as u64) <= bits, 27 | "overflowing_shr() overflow in shift right." 28 | ); 29 | 30 | fp.mant = if shift as u64 == bits { 31 | 0 32 | } else { 33 | fp.mant >> shift 34 | }; 35 | fp.exp += shift; 36 | } 37 | 38 | // Shift extended-precision float left `shift` bytes. 39 | #[inline] 40 | pub(crate) fn shl(fp: &mut ExtendedFloat, shift: i32) { 41 | let bits: u64 = mem::size_of::() as u64 * 8; 42 | debug_assert!((shift as u64) < bits, "shl() overflow in shift left."); 43 | 44 | fp.mant <<= shift; 45 | fp.exp -= shift; 46 | } 47 | -------------------------------------------------------------------------------- /src/lexical/small_powers.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | //! Pre-computed small powers. 4 | 5 | // 32 BIT 6 | #[cfg(fast_arithmetic = "32")] 7 | pub(crate) const POW5_32: [u32; 14] = [ 8 | 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 9 | 1220703125, 10 | ]; 11 | 12 | #[cfg(fast_arithmetic = "32")] 13 | pub(crate) const POW10_32: [u32; 10] = [ 14 | 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 15 | ]; 16 | 17 | // 64 BIT 18 | #[cfg(fast_arithmetic = "64")] 19 | pub(crate) const POW5_64: [u64; 28] = [ 20 | 1, 21 | 5, 22 | 25, 23 | 125, 24 | 625, 25 | 3125, 26 | 15625, 27 | 78125, 28 | 390625, 29 | 1953125, 30 | 9765625, 31 | 48828125, 32 | 244140625, 33 | 1220703125, 34 | 6103515625, 35 | 30517578125, 36 | 152587890625, 37 | 762939453125, 38 | 3814697265625, 39 | 19073486328125, 40 | 95367431640625, 41 | 476837158203125, 42 | 2384185791015625, 43 | 11920928955078125, 44 | 59604644775390625, 45 | 298023223876953125, 46 | 1490116119384765625, 47 | 7450580596923828125, 48 | ]; 49 | pub(crate) const POW10_64: [u64; 20] = [ 50 | 1, 51 | 10, 52 | 100, 53 | 1000, 54 | 10000, 55 | 100000, 56 | 1000000, 57 | 10000000, 58 | 100000000, 59 | 1000000000, 60 | 10000000000, 61 | 100000000000, 62 | 1000000000000, 63 | 10000000000000, 64 | 100000000000000, 65 | 1000000000000000, 66 | 10000000000000000, 67 | 100000000000000000, 68 | 1000000000000000000, 69 | 10000000000000000000, 70 | ]; 71 | -------------------------------------------------------------------------------- /src/macros.rs: -------------------------------------------------------------------------------- 1 | /// Construct a `serde_json::Value` from a JSON literal. 2 | /// 3 | /// ``` 4 | /// # use serde_json::json; 5 | /// # 6 | /// let value = json!({ 7 | /// "code": 200, 8 | /// "success": true, 9 | /// "payload": { 10 | /// "features": [ 11 | /// "serde", 12 | /// "json" 13 | /// ], 14 | /// "homepage": null 15 | /// } 16 | /// }); 17 | /// ``` 18 | /// 19 | /// Variables or expressions can be interpolated into the JSON literal. Any type 20 | /// interpolated into an array element or object value must implement Serde's 21 | /// `Serialize` trait, while any type interpolated into a object key must 22 | /// implement `Into`. If the `Serialize` implementation of the 23 | /// interpolated type decides to fail, or if the interpolated type contains a 24 | /// map with non-string keys, the `json!` macro will panic. 25 | /// 26 | /// ``` 27 | /// # use serde_json::json; 28 | /// # 29 | /// let code = 200; 30 | /// let features = vec!["serde", "json"]; 31 | /// 32 | /// let value = json!({ 33 | /// "code": code, 34 | /// "success": code == 200, 35 | /// "payload": { 36 | /// features[0]: features[1] 37 | /// } 38 | /// }); 39 | /// ``` 40 | /// 41 | /// Trailing commas are allowed inside both arrays and objects. 42 | /// 43 | /// ``` 44 | /// # use serde_json::json; 45 | /// # 46 | /// let value = json!([ 47 | /// "notice", 48 | /// "the", 49 | /// "trailing", 50 | /// "comma -->", 51 | /// ]); 52 | /// ``` 53 | #[macro_export] 54 | macro_rules! json { 55 | // Hide distracting implementation details from the generated rustdoc. 56 | ($($json:tt)+) => { 57 | $crate::json_internal!($($json)+) 58 | }; 59 | } 60 | 61 | // Rocket relies on this because they export their own `json!` with a different 62 | // doc comment than ours, and various Rust bugs prevent them from calling our 63 | // `json!` from their `json!` so they call `json_internal!` directly. Check with 64 | // @SergioBenitez before making breaking changes to this macro. 65 | // 66 | // Changes are fine as long as `json_internal!` does not call any new helper 67 | // macros and can still be invoked as `json_internal!($($json)+)`. 68 | #[macro_export] 69 | #[doc(hidden)] 70 | macro_rules! json_internal { 71 | ////////////////////////////////////////////////////////////////////////// 72 | // TT muncher for parsing the inside of an array [...]. Produces a vec![...] 73 | // of the elements. 74 | // 75 | // Must be invoked as: json_internal!(@array [] $($tt)*) 76 | ////////////////////////////////////////////////////////////////////////// 77 | 78 | // Done with trailing comma. 79 | (@array [$($elems:expr,)*]) => { 80 | $crate::__private::vec![$($elems,)*] 81 | }; 82 | 83 | // Done without trailing comma. 84 | (@array [$($elems:expr),*]) => { 85 | $crate::__private::vec![$($elems),*] 86 | }; 87 | 88 | // Next element is `null`. 89 | (@array [$($elems:expr,)*] null $($rest:tt)*) => { 90 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(null)] $($rest)*) 91 | }; 92 | 93 | // Next element is `true`. 94 | (@array [$($elems:expr,)*] true $($rest:tt)*) => { 95 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(true)] $($rest)*) 96 | }; 97 | 98 | // Next element is `false`. 99 | (@array [$($elems:expr,)*] false $($rest:tt)*) => { 100 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!(false)] $($rest)*) 101 | }; 102 | 103 | // Next element is an array. 104 | (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { 105 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!([$($array)*])] $($rest)*) 106 | }; 107 | 108 | // Next element is a map. 109 | (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { 110 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!({$($map)*})] $($rest)*) 111 | }; 112 | 113 | // Next element is an expression followed by comma. 114 | (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { 115 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($next),] $($rest)*) 116 | }; 117 | 118 | // Last element is an expression with no trailing comma. 119 | (@array [$($elems:expr,)*] $last:expr) => { 120 | $crate::json_internal!(@array [$($elems,)* $crate::json_internal!($last)]) 121 | }; 122 | 123 | // Comma after the most recent element. 124 | (@array [$($elems:expr),*] , $($rest:tt)*) => { 125 | $crate::json_internal!(@array [$($elems,)*] $($rest)*) 126 | }; 127 | 128 | // Unexpected token after most recent element. 129 | (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { 130 | $crate::json_unexpected!($unexpected) 131 | }; 132 | 133 | ////////////////////////////////////////////////////////////////////////// 134 | // TT muncher for parsing the inside of an object {...}. Each entry is 135 | // inserted into the given map variable. 136 | // 137 | // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) 138 | // 139 | // We require two copies of the input tokens so that we can match on one 140 | // copy and trigger errors on the other copy. 141 | ////////////////////////////////////////////////////////////////////////// 142 | 143 | // Done. 144 | (@object $object:ident () () ()) => {}; 145 | 146 | // Insert the current entry followed by trailing comma. 147 | (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { 148 | let _ = $object.insert(($($key)+).into(), $value); 149 | $crate::json_internal!(@object $object () ($($rest)*) ($($rest)*)); 150 | }; 151 | 152 | // Current entry followed by unexpected token. 153 | (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { 154 | $crate::json_unexpected!($unexpected); 155 | }; 156 | 157 | // Insert the last entry without trailing comma. 158 | (@object $object:ident [$($key:tt)+] ($value:expr)) => { 159 | let _ = $object.insert(($($key)+).into(), $value); 160 | }; 161 | 162 | // Next value is `null`. 163 | (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { 164 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(null)) $($rest)*); 165 | }; 166 | 167 | // Next value is `true`. 168 | (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { 169 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(true)) $($rest)*); 170 | }; 171 | 172 | // Next value is `false`. 173 | (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { 174 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!(false)) $($rest)*); 175 | }; 176 | 177 | // Next value is an array. 178 | (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { 179 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!([$($array)*])) $($rest)*); 180 | }; 181 | 182 | // Next value is a map. 183 | (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { 184 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!({$($map)*})) $($rest)*); 185 | }; 186 | 187 | // Next value is an expression followed by comma. 188 | (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { 189 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value)) , $($rest)*); 190 | }; 191 | 192 | // Last value is an expression with no trailing comma. 193 | (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { 194 | $crate::json_internal!(@object $object [$($key)+] ($crate::json_internal!($value))); 195 | }; 196 | 197 | // Missing value for last entry. Trigger a reasonable error message. 198 | (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { 199 | // "unexpected end of macro invocation" 200 | $crate::json_internal!(); 201 | }; 202 | 203 | // Missing colon and value for last entry. Trigger a reasonable error 204 | // message. 205 | (@object $object:ident ($($key:tt)+) () $copy:tt) => { 206 | // "unexpected end of macro invocation" 207 | $crate::json_internal!(); 208 | }; 209 | 210 | // Misplaced colon. Trigger a reasonable error message. 211 | (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { 212 | // Takes no arguments so "no rules expected the token `:`". 213 | $crate::json_unexpected!($colon); 214 | }; 215 | 216 | // Found a comma inside a key. Trigger a reasonable error message. 217 | (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { 218 | // Takes no arguments so "no rules expected the token `,`". 219 | $crate::json_unexpected!($comma); 220 | }; 221 | 222 | // Key is fully parenthesized. This avoids clippy double_parens false 223 | // positives because the parenthesization may be necessary here. 224 | (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { 225 | $crate::json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); 226 | }; 227 | 228 | // Refuse to absorb colon token into key expression. 229 | (@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => { 230 | $crate::json_expect_expr_comma!($($unexpected)+); 231 | }; 232 | 233 | // Munch a token into the current key. 234 | (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { 235 | $crate::json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); 236 | }; 237 | 238 | ////////////////////////////////////////////////////////////////////////// 239 | // The main implementation. 240 | // 241 | // Must be invoked as: json_internal!($($json)+) 242 | ////////////////////////////////////////////////////////////////////////// 243 | 244 | (null) => { 245 | $crate::Value::Null 246 | }; 247 | 248 | (true) => { 249 | $crate::Value::Bool(true) 250 | }; 251 | 252 | (false) => { 253 | $crate::Value::Bool(false) 254 | }; 255 | 256 | ([]) => { 257 | $crate::Value::Array($crate::__private::vec![]) 258 | }; 259 | 260 | ([ $($tt:tt)+ ]) => { 261 | $crate::Value::Array($crate::json_internal!(@array [] $($tt)+)) 262 | }; 263 | 264 | ({}) => { 265 | $crate::Value::Object($crate::Map::new()) 266 | }; 267 | 268 | ({ $($tt:tt)+ }) => { 269 | $crate::Value::Object({ 270 | let mut object = $crate::Map::new(); 271 | $crate::json_internal!(@object object () ($($tt)+) ($($tt)+)); 272 | object 273 | }) 274 | }; 275 | 276 | // Any Serialize type: numbers, strings, struct literals, variables etc. 277 | // Must be below every other rule. 278 | ($other:expr) => { 279 | $crate::to_value(&$other).unwrap() 280 | }; 281 | } 282 | 283 | // Used by old versions of Rocket. 284 | // Unused since https://github.com/rwf2/Rocket/commit/c74bcfd40a47b35330db6cafb88e4f3da83e0d17 285 | #[macro_export] 286 | #[doc(hidden)] 287 | macro_rules! json_internal_vec { 288 | ($($content:tt)*) => { 289 | vec![$($content)*] 290 | }; 291 | } 292 | 293 | #[macro_export] 294 | #[doc(hidden)] 295 | macro_rules! json_unexpected { 296 | () => {}; 297 | } 298 | 299 | #[macro_export] 300 | #[doc(hidden)] 301 | macro_rules! json_expect_expr_comma { 302 | ($e:expr , $($tt:tt)*) => {}; 303 | } 304 | -------------------------------------------------------------------------------- /src/value/from.rs: -------------------------------------------------------------------------------- 1 | use super::Value; 2 | use crate::map::Map; 3 | use crate::number::Number; 4 | use alloc::borrow::{Cow, ToOwned}; 5 | use alloc::string::String; 6 | use alloc::vec::Vec; 7 | 8 | macro_rules! from_integer { 9 | ($($ty:ident)*) => { 10 | $( 11 | impl From<$ty> for Value { 12 | fn from(n: $ty) -> Self { 13 | Value::Number(n.into()) 14 | } 15 | } 16 | )* 17 | }; 18 | } 19 | 20 | from_integer! { 21 | i8 i16 i32 i64 isize 22 | u8 u16 u32 u64 usize 23 | } 24 | 25 | #[cfg(feature = "arbitrary_precision")] 26 | from_integer! { 27 | i128 u128 28 | } 29 | 30 | impl From for Value { 31 | /// Convert 32-bit floating point number to `Value::Number`, or 32 | /// `Value::Null` if infinite or NaN. 33 | /// 34 | /// # Examples 35 | /// 36 | /// ``` 37 | /// use serde_json::Value; 38 | /// 39 | /// let f: f32 = 13.37; 40 | /// let x: Value = f.into(); 41 | /// ``` 42 | fn from(f: f32) -> Self { 43 | Number::from_f32(f).map_or(Value::Null, Value::Number) 44 | } 45 | } 46 | 47 | impl From for Value { 48 | /// Convert 64-bit floating point number to `Value::Number`, or 49 | /// `Value::Null` if infinite or NaN. 50 | /// 51 | /// # Examples 52 | /// 53 | /// ``` 54 | /// use serde_json::Value; 55 | /// 56 | /// let f: f64 = 13.37; 57 | /// let x: Value = f.into(); 58 | /// ``` 59 | fn from(f: f64) -> Self { 60 | Number::from_f64(f).map_or(Value::Null, Value::Number) 61 | } 62 | } 63 | 64 | impl From for Value { 65 | /// Convert boolean to `Value::Bool`. 66 | /// 67 | /// # Examples 68 | /// 69 | /// ``` 70 | /// use serde_json::Value; 71 | /// 72 | /// let b = false; 73 | /// let x: Value = b.into(); 74 | /// ``` 75 | fn from(f: bool) -> Self { 76 | Value::Bool(f) 77 | } 78 | } 79 | 80 | impl From for Value { 81 | /// Convert `String` to `Value::String`. 82 | /// 83 | /// # Examples 84 | /// 85 | /// ``` 86 | /// use serde_json::Value; 87 | /// 88 | /// let s: String = "lorem".to_owned(); 89 | /// let x: Value = s.into(); 90 | /// ``` 91 | fn from(f: String) -> Self { 92 | Value::String(f) 93 | } 94 | } 95 | 96 | impl From<&str> for Value { 97 | /// Convert string slice to `Value::String`. 98 | /// 99 | /// # Examples 100 | /// 101 | /// ``` 102 | /// use serde_json::Value; 103 | /// 104 | /// let s: &str = "lorem"; 105 | /// let x: Value = s.into(); 106 | /// ``` 107 | fn from(f: &str) -> Self { 108 | Value::String(f.to_owned()) 109 | } 110 | } 111 | 112 | impl<'a> From> for Value { 113 | /// Convert copy-on-write string to `Value::String`. 114 | /// 115 | /// # Examples 116 | /// 117 | /// ``` 118 | /// use serde_json::Value; 119 | /// use std::borrow::Cow; 120 | /// 121 | /// let s: Cow = Cow::Borrowed("lorem"); 122 | /// let x: Value = s.into(); 123 | /// ``` 124 | /// 125 | /// ``` 126 | /// use serde_json::Value; 127 | /// use std::borrow::Cow; 128 | /// 129 | /// let s: Cow = Cow::Owned("lorem".to_owned()); 130 | /// let x: Value = s.into(); 131 | /// ``` 132 | fn from(f: Cow<'a, str>) -> Self { 133 | Value::String(f.into_owned()) 134 | } 135 | } 136 | 137 | impl From for Value { 138 | /// Convert `Number` to `Value::Number`. 139 | /// 140 | /// # Examples 141 | /// 142 | /// ``` 143 | /// use serde_json::{Number, Value}; 144 | /// 145 | /// let n = Number::from(7); 146 | /// let x: Value = n.into(); 147 | /// ``` 148 | fn from(f: Number) -> Self { 149 | Value::Number(f) 150 | } 151 | } 152 | 153 | impl From> for Value { 154 | /// Convert map (with string keys) to `Value::Object`. 155 | /// 156 | /// # Examples 157 | /// 158 | /// ``` 159 | /// use serde_json::{Map, Value}; 160 | /// 161 | /// let mut m = Map::new(); 162 | /// m.insert("Lorem".to_owned(), "ipsum".into()); 163 | /// let x: Value = m.into(); 164 | /// ``` 165 | fn from(f: Map) -> Self { 166 | Value::Object(f) 167 | } 168 | } 169 | 170 | impl> From> for Value { 171 | /// Convert a `Vec` to `Value::Array`. 172 | /// 173 | /// # Examples 174 | /// 175 | /// ``` 176 | /// use serde_json::Value; 177 | /// 178 | /// let v = vec!["lorem", "ipsum", "dolor"]; 179 | /// let x: Value = v.into(); 180 | /// ``` 181 | fn from(f: Vec) -> Self { 182 | Value::Array(f.into_iter().map(Into::into).collect()) 183 | } 184 | } 185 | 186 | impl, const N: usize> From<[T; N]> for Value { 187 | fn from(array: [T; N]) -> Self { 188 | Value::Array(array.into_iter().map(Into::into).collect()) 189 | } 190 | } 191 | 192 | impl> From<&[T]> for Value { 193 | /// Convert a slice to `Value::Array`. 194 | /// 195 | /// # Examples 196 | /// 197 | /// ``` 198 | /// use serde_json::Value; 199 | /// 200 | /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; 201 | /// let x: Value = v.into(); 202 | /// ``` 203 | fn from(f: &[T]) -> Self { 204 | Value::Array(f.iter().cloned().map(Into::into).collect()) 205 | } 206 | } 207 | 208 | impl> FromIterator for Value { 209 | /// Create a `Value::Array` by collecting an iterator of array elements. 210 | /// 211 | /// # Examples 212 | /// 213 | /// ``` 214 | /// use serde_json::Value; 215 | /// 216 | /// let v = std::iter::repeat(42).take(5); 217 | /// let x: Value = v.collect(); 218 | /// ``` 219 | /// 220 | /// ``` 221 | /// use serde_json::Value; 222 | /// 223 | /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; 224 | /// let x: Value = v.into_iter().collect(); 225 | /// ``` 226 | /// 227 | /// ``` 228 | /// use std::iter::FromIterator; 229 | /// use serde_json::Value; 230 | /// 231 | /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); 232 | /// ``` 233 | fn from_iter>(iter: I) -> Self { 234 | Value::Array(iter.into_iter().map(Into::into).collect()) 235 | } 236 | } 237 | 238 | impl, V: Into> FromIterator<(K, V)> for Value { 239 | /// Create a `Value::Object` by collecting an iterator of key-value pairs. 240 | /// 241 | /// # Examples 242 | /// 243 | /// ``` 244 | /// use serde_json::Value; 245 | /// 246 | /// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)]; 247 | /// let x: Value = v.into_iter().collect(); 248 | /// ``` 249 | fn from_iter>(iter: I) -> Self { 250 | Value::Object( 251 | iter.into_iter() 252 | .map(|(k, v)| (k.into(), v.into())) 253 | .collect(), 254 | ) 255 | } 256 | } 257 | 258 | impl From<()> for Value { 259 | /// Convert `()` to `Value::Null`. 260 | /// 261 | /// # Examples 262 | /// 263 | /// ``` 264 | /// use serde_json::Value; 265 | /// 266 | /// let u = (); 267 | /// let x: Value = u.into(); 268 | /// ``` 269 | fn from((): ()) -> Self { 270 | Value::Null 271 | } 272 | } 273 | 274 | impl From> for Value 275 | where 276 | T: Into, 277 | { 278 | fn from(opt: Option) -> Self { 279 | match opt { 280 | None => Value::Null, 281 | Some(value) => Into::into(value), 282 | } 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /src/value/index.rs: -------------------------------------------------------------------------------- 1 | use super::Value; 2 | use crate::map::Map; 3 | use alloc::borrow::ToOwned; 4 | use alloc::string::String; 5 | use core::fmt::{self, Display}; 6 | use core::ops; 7 | 8 | /// A type that can be used to index into a `serde_json::Value`. 9 | /// 10 | /// The [`get`] and [`get_mut`] methods of `Value` accept any type that 11 | /// implements `Index`, as does the [square-bracket indexing operator]. This 12 | /// trait is implemented for strings which are used as the index into a JSON 13 | /// map, and for `usize` which is used as the index into a JSON array. 14 | /// 15 | /// [`get`]: Value::get 16 | /// [`get_mut`]: Value::get_mut 17 | /// [square-bracket indexing operator]: Value#impl-Index%3CI%3E-for-Value 18 | /// 19 | /// This trait is sealed and cannot be implemented for types outside of 20 | /// `serde_json`. 21 | /// 22 | /// # Examples 23 | /// 24 | /// ``` 25 | /// # use serde_json::json; 26 | /// # 27 | /// let data = json!({ "inner": [1, 2, 3] }); 28 | /// 29 | /// // Data is a JSON map so it can be indexed with a string. 30 | /// let inner = &data["inner"]; 31 | /// 32 | /// // Inner is a JSON array so it can be indexed with an integer. 33 | /// let first = &inner[0]; 34 | /// 35 | /// assert_eq!(first, 1); 36 | /// ``` 37 | pub trait Index: private::Sealed { 38 | /// Return None if the key is not already in the array or object. 39 | #[doc(hidden)] 40 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; 41 | 42 | /// Return None if the key is not already in the array or object. 43 | #[doc(hidden)] 44 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; 45 | 46 | /// Panic if array index out of bounds. If key is not already in the object, 47 | /// insert it with a value of null. Panic if Value is a type that cannot be 48 | /// indexed into, except if Value is null then it can be treated as an empty 49 | /// object. 50 | #[doc(hidden)] 51 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; 52 | } 53 | 54 | impl Index for usize { 55 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 56 | match v { 57 | Value::Array(vec) => vec.get(*self), 58 | _ => None, 59 | } 60 | } 61 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 62 | match v { 63 | Value::Array(vec) => vec.get_mut(*self), 64 | _ => None, 65 | } 66 | } 67 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 68 | match v { 69 | Value::Array(vec) => { 70 | let len = vec.len(); 71 | vec.get_mut(*self).unwrap_or_else(|| { 72 | panic!( 73 | "cannot access index {} of JSON array of length {}", 74 | self, len 75 | ) 76 | }) 77 | } 78 | _ => panic!("cannot access index {} of JSON {}", self, Type(v)), 79 | } 80 | } 81 | } 82 | 83 | impl Index for str { 84 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 85 | match v { 86 | Value::Object(map) => map.get(self), 87 | _ => None, 88 | } 89 | } 90 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 91 | match v { 92 | Value::Object(map) => map.get_mut(self), 93 | _ => None, 94 | } 95 | } 96 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 97 | if let Value::Null = v { 98 | *v = Value::Object(Map::new()); 99 | } 100 | match v { 101 | Value::Object(map) => map.entry(self.to_owned()).or_insert(Value::Null), 102 | _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), 103 | } 104 | } 105 | } 106 | 107 | impl Index for String { 108 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 109 | self[..].index_into(v) 110 | } 111 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 112 | self[..].index_into_mut(v) 113 | } 114 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 115 | self[..].index_or_insert(v) 116 | } 117 | } 118 | 119 | impl Index for &T 120 | where 121 | T: ?Sized + Index, 122 | { 123 | fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { 124 | (**self).index_into(v) 125 | } 126 | fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { 127 | (**self).index_into_mut(v) 128 | } 129 | fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { 130 | (**self).index_or_insert(v) 131 | } 132 | } 133 | 134 | // Prevent users from implementing the Index trait. 135 | mod private { 136 | pub trait Sealed {} 137 | impl Sealed for usize {} 138 | impl Sealed for str {} 139 | impl Sealed for alloc::string::String {} 140 | impl Sealed for &T where T: ?Sized + Sealed {} 141 | } 142 | 143 | /// Used in panic messages. 144 | struct Type<'a>(&'a Value); 145 | 146 | impl<'a> Display for Type<'a> { 147 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 148 | match *self.0 { 149 | Value::Null => formatter.write_str("null"), 150 | Value::Bool(_) => formatter.write_str("boolean"), 151 | Value::Number(_) => formatter.write_str("number"), 152 | Value::String(_) => formatter.write_str("string"), 153 | Value::Array(_) => formatter.write_str("array"), 154 | Value::Object(_) => formatter.write_str("object"), 155 | } 156 | } 157 | } 158 | 159 | // The usual semantics of Index is to panic on invalid indexing. 160 | // 161 | // That said, the usual semantics are for things like Vec and BTreeMap which 162 | // have different use cases than Value. If you are working with a Vec, you know 163 | // that you are working with a Vec and you can get the len of the Vec and make 164 | // sure your indices are within bounds. The Value use cases are more 165 | // loosey-goosey. You got some JSON from an endpoint and you want to pull values 166 | // out of it. Outside of this Index impl, you already have the option of using 167 | // value.as_array() and working with the Vec directly, or matching on 168 | // Value::Array and getting the Vec directly. The Index impl means you can skip 169 | // that and index directly into the thing using a concise syntax. You don't have 170 | // to check the type, you don't have to check the len, it is all about what you 171 | // expect the Value to look like. 172 | // 173 | // Basically the use cases that would be well served by panicking here are 174 | // better served by using one of the other approaches: get and get_mut, 175 | // as_array, or match. The value of this impl is that it adds a way of working 176 | // with Value that is not well served by the existing approaches: concise and 177 | // careless and sometimes that is exactly what you want. 178 | impl ops::Index for Value 179 | where 180 | I: Index, 181 | { 182 | type Output = Value; 183 | 184 | /// Index into a `serde_json::Value` using the syntax `value[0]` or 185 | /// `value["k"]`. 186 | /// 187 | /// Returns `Value::Null` if the type of `self` does not match the type of 188 | /// the index, for example if the index is a string and `self` is an array 189 | /// or a number. Also returns `Value::Null` if the given key does not exist 190 | /// in the map or the given index is not within the bounds of the array. 191 | /// 192 | /// For retrieving deeply nested values, you should have a look at the 193 | /// `Value::pointer` method. 194 | /// 195 | /// # Examples 196 | /// 197 | /// ``` 198 | /// # use serde_json::json; 199 | /// # 200 | /// let data = json!({ 201 | /// "x": { 202 | /// "y": ["z", "zz"] 203 | /// } 204 | /// }); 205 | /// 206 | /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); 207 | /// assert_eq!(data["x"]["y"][0], json!("z")); 208 | /// 209 | /// assert_eq!(data["a"], json!(null)); // returns null for undefined values 210 | /// assert_eq!(data["a"]["b"], json!(null)); // does not panic 211 | /// ``` 212 | fn index(&self, index: I) -> &Value { 213 | static NULL: Value = Value::Null; 214 | index.index_into(self).unwrap_or(&NULL) 215 | } 216 | } 217 | 218 | impl ops::IndexMut for Value 219 | where 220 | I: Index, 221 | { 222 | /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or 223 | /// `value["k"] = ...`. 224 | /// 225 | /// If the index is a number, the value must be an array of length bigger 226 | /// than the index. Indexing into a value that is not an array or an array 227 | /// that is too small will panic. 228 | /// 229 | /// If the index is a string, the value must be an object or null which is 230 | /// treated like an empty object. If the key is not already present in the 231 | /// object, it will be inserted with a value of null. Indexing into a value 232 | /// that is neither an object nor null will panic. 233 | /// 234 | /// # Examples 235 | /// 236 | /// ``` 237 | /// # use serde_json::json; 238 | /// # 239 | /// let mut data = json!({ "x": 0 }); 240 | /// 241 | /// // replace an existing key 242 | /// data["x"] = json!(1); 243 | /// 244 | /// // insert a new key 245 | /// data["y"] = json!([false, false, false]); 246 | /// 247 | /// // replace an array value 248 | /// data["y"][0] = json!(true); 249 | /// 250 | /// // inserted a deeply nested key 251 | /// data["a"]["b"]["c"]["d"] = json!(true); 252 | /// 253 | /// println!("{}", data); 254 | /// ``` 255 | fn index_mut(&mut self, index: I) -> &mut Value { 256 | index.index_or_insert(self) 257 | } 258 | } 259 | -------------------------------------------------------------------------------- /src/value/partial_eq.rs: -------------------------------------------------------------------------------- 1 | use super::Value; 2 | use alloc::string::String; 3 | 4 | fn eq_i64(value: &Value, other: i64) -> bool { 5 | value.as_i64() == Some(other) 6 | } 7 | 8 | fn eq_u64(value: &Value, other: u64) -> bool { 9 | value.as_u64() == Some(other) 10 | } 11 | 12 | fn eq_f32(value: &Value, other: f32) -> bool { 13 | match value { 14 | Value::Number(n) => n.as_f32() == Some(other), 15 | _ => false, 16 | } 17 | } 18 | 19 | fn eq_f64(value: &Value, other: f64) -> bool { 20 | value.as_f64() == Some(other) 21 | } 22 | 23 | fn eq_bool(value: &Value, other: bool) -> bool { 24 | value.as_bool() == Some(other) 25 | } 26 | 27 | fn eq_str(value: &Value, other: &str) -> bool { 28 | value.as_str() == Some(other) 29 | } 30 | 31 | impl PartialEq for Value { 32 | fn eq(&self, other: &str) -> bool { 33 | eq_str(self, other) 34 | } 35 | } 36 | 37 | impl PartialEq<&str> for Value { 38 | fn eq(&self, other: &&str) -> bool { 39 | eq_str(self, *other) 40 | } 41 | } 42 | 43 | impl PartialEq for str { 44 | fn eq(&self, other: &Value) -> bool { 45 | eq_str(other, self) 46 | } 47 | } 48 | 49 | impl PartialEq for &str { 50 | fn eq(&self, other: &Value) -> bool { 51 | eq_str(other, *self) 52 | } 53 | } 54 | 55 | impl PartialEq for Value { 56 | fn eq(&self, other: &String) -> bool { 57 | eq_str(self, other.as_str()) 58 | } 59 | } 60 | 61 | impl PartialEq for String { 62 | fn eq(&self, other: &Value) -> bool { 63 | eq_str(other, self.as_str()) 64 | } 65 | } 66 | 67 | macro_rules! partialeq_numeric { 68 | ($($eq:ident [$($ty:ty)*])*) => { 69 | $($( 70 | impl PartialEq<$ty> for Value { 71 | fn eq(&self, other: &$ty) -> bool { 72 | $eq(self, *other as _) 73 | } 74 | } 75 | 76 | impl PartialEq for $ty { 77 | fn eq(&self, other: &Value) -> bool { 78 | $eq(other, *self as _) 79 | } 80 | } 81 | 82 | impl<'a> PartialEq<$ty> for &'a Value { 83 | fn eq(&self, other: &$ty) -> bool { 84 | $eq(*self, *other as _) 85 | } 86 | } 87 | 88 | impl<'a> PartialEq<$ty> for &'a mut Value { 89 | fn eq(&self, other: &$ty) -> bool { 90 | $eq(*self, *other as _) 91 | } 92 | } 93 | )*)* 94 | } 95 | } 96 | 97 | partialeq_numeric! { 98 | eq_i64[i8 i16 i32 i64 isize] 99 | eq_u64[u8 u16 u32 u64 usize] 100 | eq_f32[f32] 101 | eq_f64[f64] 102 | eq_bool[bool] 103 | } 104 | -------------------------------------------------------------------------------- /tests/compiletest.rs: -------------------------------------------------------------------------------- 1 | #[rustversion::attr(not(nightly), ignore = "requires nightly")] 2 | #[cfg_attr(miri, ignore = "incompatible with miri")] 3 | #[test] 4 | fn ui() { 5 | let t = trybuild::TestCases::new(); 6 | t.compile_fail("tests/ui/*.rs"); 7 | } 8 | -------------------------------------------------------------------------------- /tests/crate/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /tests/crate/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json_test" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [lib] 9 | path = "test.rs" 10 | 11 | [dependencies] 12 | serde_json = { path = "../..", default-features = false } 13 | 14 | [features] 15 | default = ["std"] 16 | std = ["serde_json/std"] 17 | alloc = ["serde_json/alloc"] 18 | #preserve_order = ["serde_json/preserve_order"] 19 | float_roundtrip = ["serde_json/float_roundtrip"] 20 | arbitrary_precision = ["serde_json/arbitrary_precision"] 21 | raw_value = ["serde_json/raw_value"] 22 | unbounded_depth = ["serde_json/unbounded_depth"] 23 | -------------------------------------------------------------------------------- /tests/crate/test.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | 3 | pub use serde_json::*; 4 | -------------------------------------------------------------------------------- /tests/debug.rs: -------------------------------------------------------------------------------- 1 | use indoc::indoc; 2 | use serde_json::{json, Number, Value}; 3 | 4 | #[test] 5 | fn number() { 6 | assert_eq!(format!("{:?}", Number::from(1)), "Number(1)"); 7 | assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)"); 8 | assert_eq!( 9 | format!("{:?}", Number::from_f64(1.0).unwrap()), 10 | "Number(1.0)" 11 | ); 12 | } 13 | 14 | #[test] 15 | fn value_null() { 16 | assert_eq!(format!("{:?}", json!(null)), "Null"); 17 | } 18 | 19 | #[test] 20 | fn value_bool() { 21 | assert_eq!(format!("{:?}", json!(true)), "Bool(true)"); 22 | assert_eq!(format!("{:?}", json!(false)), "Bool(false)"); 23 | } 24 | 25 | #[test] 26 | fn value_number() { 27 | assert_eq!(format!("{:?}", json!(1)), "Number(1)"); 28 | assert_eq!(format!("{:?}", json!(-1)), "Number(-1)"); 29 | assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)"); 30 | assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1" 31 | assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41"); 32 | } 33 | 34 | #[test] 35 | fn value_string() { 36 | assert_eq!(format!("{:?}", json!("s")), "String(\"s\")"); 37 | } 38 | 39 | #[test] 40 | fn value_array() { 41 | assert_eq!(format!("{:?}", json!([])), "Array []"); 42 | } 43 | 44 | #[test] 45 | fn value_object() { 46 | assert_eq!(format!("{:?}", json!({})), "Object {}"); 47 | } 48 | 49 | #[test] 50 | fn error() { 51 | let err = serde_json::from_str::("{0}").unwrap_err(); 52 | let expected = "Error(\"key must be a string\", line: 1, column: 2)"; 53 | assert_eq!(format!("{:?}", err), expected); 54 | } 55 | 56 | #[test] 57 | fn indented() { 58 | let j = json!({ 59 | "Array": [true], 60 | "Bool": true, 61 | "EmptyArray": [], 62 | "EmptyObject": {}, 63 | "Null": null, 64 | "Number": 1, 65 | "String": "...", 66 | }); 67 | let expected = indoc! {r#" 68 | Object { 69 | "Array": Array [ 70 | Bool(true), 71 | ], 72 | "Bool": Bool(true), 73 | "EmptyArray": Array [], 74 | "EmptyObject": Object {}, 75 | "Null": Null, 76 | "Number": Number(1), 77 | "String": String("..."), 78 | }"# 79 | }; 80 | assert_eq!(format!("{:#?}", j), expected); 81 | } 82 | -------------------------------------------------------------------------------- /tests/lexical.rs: -------------------------------------------------------------------------------- 1 | #![allow( 2 | clippy::cast_lossless, 3 | clippy::cast_possible_truncation, 4 | clippy::cast_possible_wrap, 5 | clippy::cast_precision_loss, 6 | clippy::cast_sign_loss, 7 | clippy::comparison_chain, 8 | clippy::doc_markdown, 9 | clippy::excessive_precision, 10 | clippy::float_cmp, 11 | clippy::if_not_else, 12 | clippy::let_underscore_untyped, 13 | clippy::module_name_repetitions, 14 | clippy::needless_late_init, 15 | clippy::question_mark, 16 | clippy::shadow_unrelated, 17 | clippy::similar_names, 18 | clippy::single_match_else, 19 | clippy::too_many_lines, 20 | clippy::unreadable_literal, 21 | clippy::unseparated_literal_suffix, 22 | clippy::wildcard_imports 23 | )] 24 | 25 | extern crate alloc; 26 | 27 | #[path = "../src/lexical/mod.rs"] 28 | mod lexical; 29 | 30 | #[path = "lexical/algorithm.rs"] 31 | mod algorithm; 32 | 33 | #[path = "lexical/exponent.rs"] 34 | mod exponent; 35 | 36 | #[path = "lexical/float.rs"] 37 | mod float; 38 | 39 | #[path = "lexical/math.rs"] 40 | mod math; 41 | 42 | #[path = "lexical/num.rs"] 43 | mod num; 44 | 45 | #[path = "lexical/parse.rs"] 46 | mod parse; 47 | 48 | #[path = "lexical/rounding.rs"] 49 | mod rounding; 50 | -------------------------------------------------------------------------------- /tests/lexical/algorithm.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use crate::lexical::algorithm::*; 4 | use crate::lexical::num::Float; 5 | 6 | #[test] 7 | fn float_fast_path_test() { 8 | // valid 9 | let mantissa = (1 << f32::MANTISSA_SIZE) - 1; 10 | let (min_exp, max_exp) = f32::exponent_limit(); 11 | for exp in min_exp..=max_exp { 12 | let f = fast_path::(mantissa, exp); 13 | assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); 14 | } 15 | 16 | // Check slightly above valid exponents 17 | let f = fast_path::(123, 15); 18 | assert_eq!(f, Some(1.23e+17)); 19 | 20 | // Exponent is 1 too high, pushes over the mantissa. 21 | let f = fast_path::(123, 16); 22 | assert!(f.is_none()); 23 | 24 | // Mantissa is too large, checked_mul should overflow. 25 | let f = fast_path::(mantissa, 11); 26 | assert!(f.is_none()); 27 | 28 | // invalid exponents 29 | let (min_exp, max_exp) = f32::exponent_limit(); 30 | let f = fast_path::(mantissa, min_exp - 1); 31 | assert!(f.is_none(), "exponent under min_exp"); 32 | 33 | let f = fast_path::(mantissa, max_exp + 1); 34 | assert!(f.is_none(), "exponent above max_exp"); 35 | } 36 | 37 | #[test] 38 | fn double_fast_path_test() { 39 | // valid 40 | let mantissa = (1 << f64::MANTISSA_SIZE) - 1; 41 | let (min_exp, max_exp) = f64::exponent_limit(); 42 | for exp in min_exp..=max_exp { 43 | let f = fast_path::(mantissa, exp); 44 | assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp)); 45 | } 46 | 47 | // invalid exponents 48 | let (min_exp, max_exp) = f64::exponent_limit(); 49 | let f = fast_path::(mantissa, min_exp - 1); 50 | assert!(f.is_none(), "exponent under min_exp"); 51 | 52 | let f = fast_path::(mantissa, max_exp + 1); 53 | assert!(f.is_none(), "exponent above max_exp"); 54 | 55 | assert_eq!( 56 | Some(0.04628372940652459), 57 | fast_path::(4628372940652459, -17) 58 | ); 59 | assert_eq!(None, fast_path::(26383446160308229, -272)); 60 | } 61 | 62 | #[test] 63 | fn moderate_path_test() { 64 | let (f, valid) = moderate_path::(1234567890, -1, false); 65 | assert!(valid, "should be valid"); 66 | assert_eq!(f.into_float::(), 123456789.0); 67 | 68 | let (f, valid) = moderate_path::(1234567891, -1, false); 69 | assert!(valid, "should be valid"); 70 | assert_eq!(f.into_float::(), 123456789.1); 71 | 72 | let (f, valid) = moderate_path::(12345678912, -2, false); 73 | assert!(valid, "should be valid"); 74 | assert_eq!(f.into_float::(), 123456789.12); 75 | 76 | let (f, valid) = moderate_path::(123456789123, -3, false); 77 | assert!(valid, "should be valid"); 78 | assert_eq!(f.into_float::(), 123456789.123); 79 | 80 | let (f, valid) = moderate_path::(1234567891234, -4, false); 81 | assert!(valid, "should be valid"); 82 | assert_eq!(f.into_float::(), 123456789.1234); 83 | 84 | let (f, valid) = moderate_path::(12345678912345, -5, false); 85 | assert!(valid, "should be valid"); 86 | assert_eq!(f.into_float::(), 123456789.12345); 87 | 88 | let (f, valid) = moderate_path::(123456789123456, -6, false); 89 | assert!(valid, "should be valid"); 90 | assert_eq!(f.into_float::(), 123456789.123456); 91 | 92 | let (f, valid) = moderate_path::(1234567891234567, -7, false); 93 | assert!(valid, "should be valid"); 94 | assert_eq!(f.into_float::(), 123456789.1234567); 95 | 96 | let (f, valid) = moderate_path::(12345678912345679, -8, false); 97 | assert!(valid, "should be valid"); 98 | assert_eq!(f.into_float::(), 123456789.12345679); 99 | 100 | let (f, valid) = moderate_path::(4628372940652459, -17, false); 101 | assert!(valid, "should be valid"); 102 | assert_eq!(f.into_float::(), 0.04628372940652459); 103 | 104 | let (f, valid) = moderate_path::(26383446160308229, -272, false); 105 | assert!(valid, "should be valid"); 106 | assert_eq!(f.into_float::(), 2.6383446160308229e-256); 107 | 108 | let (_, valid) = moderate_path::(26383446160308230, -272, false); 109 | assert!(!valid, "should be invalid"); 110 | } 111 | -------------------------------------------------------------------------------- /tests/lexical/exponent.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use crate::lexical::exponent::*; 4 | 5 | #[test] 6 | fn scientific_exponent_test() { 7 | // 0 digits in the integer 8 | assert_eq!(scientific_exponent(0, 0, 5), -6); 9 | assert_eq!(scientific_exponent(10, 0, 5), 4); 10 | assert_eq!(scientific_exponent(-10, 0, 5), -16); 11 | 12 | // >0 digits in the integer 13 | assert_eq!(scientific_exponent(0, 1, 5), 0); 14 | assert_eq!(scientific_exponent(0, 2, 5), 1); 15 | assert_eq!(scientific_exponent(0, 2, 20), 1); 16 | assert_eq!(scientific_exponent(10, 2, 20), 11); 17 | assert_eq!(scientific_exponent(-10, 2, 20), -9); 18 | 19 | // Underflow 20 | assert_eq!(scientific_exponent(i32::MIN, 0, 0), i32::MIN); 21 | assert_eq!(scientific_exponent(i32::MIN, 0, 5), i32::MIN); 22 | 23 | // Overflow 24 | assert_eq!(scientific_exponent(i32::MAX, 0, 0), i32::MAX - 1); 25 | assert_eq!(scientific_exponent(i32::MAX, 5, 0), i32::MAX); 26 | } 27 | 28 | #[test] 29 | fn mantissa_exponent_test() { 30 | assert_eq!(mantissa_exponent(10, 5, 0), 5); 31 | assert_eq!(mantissa_exponent(0, 5, 0), -5); 32 | assert_eq!(mantissa_exponent(i32::MAX, 5, 0), i32::MAX - 5); 33 | assert_eq!(mantissa_exponent(i32::MAX, 0, 5), i32::MAX); 34 | assert_eq!(mantissa_exponent(i32::MIN, 5, 0), i32::MIN); 35 | assert_eq!(mantissa_exponent(i32::MIN, 0, 5), i32::MIN + 5); 36 | } 37 | -------------------------------------------------------------------------------- /tests/lexical/math.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use crate::lexical::math::{Limb, Math}; 4 | use std::cmp; 5 | 6 | #[derive(Clone, Default)] 7 | struct Bigint { 8 | data: Vec, 9 | } 10 | 11 | impl Math for Bigint { 12 | fn data(&self) -> &Vec { 13 | &self.data 14 | } 15 | 16 | fn data_mut(&mut self) -> &mut Vec { 17 | &mut self.data 18 | } 19 | } 20 | 21 | #[cfg(fast_arithmetic = "32")] 22 | pub(crate) fn from_u32(x: &[u32]) -> Vec { 23 | x.iter().cloned().collect() 24 | } 25 | 26 | #[cfg(fast_arithmetic = "64")] 27 | pub(crate) fn from_u32(x: &[u32]) -> Vec { 28 | let mut v = Vec::::default(); 29 | for xi in x.chunks(2) { 30 | match xi.len() { 31 | 1 => v.push(xi[0] as u64), 32 | 2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)), 33 | _ => unreachable!(), 34 | } 35 | } 36 | 37 | v 38 | } 39 | 40 | #[test] 41 | fn compare_test() { 42 | // Simple 43 | let x = Bigint { 44 | data: from_u32(&[1]), 45 | }; 46 | let y = Bigint { 47 | data: from_u32(&[2]), 48 | }; 49 | assert_eq!(x.compare(&y), cmp::Ordering::Less); 50 | assert_eq!(x.compare(&x), cmp::Ordering::Equal); 51 | assert_eq!(y.compare(&x), cmp::Ordering::Greater); 52 | 53 | // Check asymmetric 54 | let x = Bigint { 55 | data: from_u32(&[5, 1]), 56 | }; 57 | let y = Bigint { 58 | data: from_u32(&[2]), 59 | }; 60 | assert_eq!(x.compare(&y), cmp::Ordering::Greater); 61 | assert_eq!(x.compare(&x), cmp::Ordering::Equal); 62 | assert_eq!(y.compare(&x), cmp::Ordering::Less); 63 | 64 | // Check when we use reverse ordering properly. 65 | let x = Bigint { 66 | data: from_u32(&[5, 1, 9]), 67 | }; 68 | let y = Bigint { 69 | data: from_u32(&[6, 2, 8]), 70 | }; 71 | assert_eq!(x.compare(&y), cmp::Ordering::Greater); 72 | assert_eq!(x.compare(&x), cmp::Ordering::Equal); 73 | assert_eq!(y.compare(&x), cmp::Ordering::Less); 74 | 75 | // Complex scenario, check it properly uses reverse ordering. 76 | let x = Bigint { 77 | data: from_u32(&[0, 1, 9]), 78 | }; 79 | let y = Bigint { 80 | data: from_u32(&[4294967295, 0, 9]), 81 | }; 82 | assert_eq!(x.compare(&y), cmp::Ordering::Greater); 83 | assert_eq!(x.compare(&x), cmp::Ordering::Equal); 84 | assert_eq!(y.compare(&x), cmp::Ordering::Less); 85 | } 86 | 87 | #[test] 88 | fn hi64_test() { 89 | assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false)); 90 | assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false)); 91 | assert_eq!( 92 | Bigint::from_u64(0xAB00000000).hi64(), 93 | (0xAB00000000000000, false) 94 | ); 95 | assert_eq!( 96 | Bigint::from_u64(0xA23456789A).hi64(), 97 | (0xA23456789A000000, false) 98 | ); 99 | } 100 | 101 | #[test] 102 | fn bit_length_test() { 103 | let x = Bigint { 104 | data: from_u32(&[0, 0, 0, 1]), 105 | }; 106 | assert_eq!(x.bit_length(), 97); 107 | 108 | let x = Bigint { 109 | data: from_u32(&[0, 0, 0, 3]), 110 | }; 111 | assert_eq!(x.bit_length(), 98); 112 | 113 | let x = Bigint { 114 | data: from_u32(&[1 << 31]), 115 | }; 116 | assert_eq!(x.bit_length(), 32); 117 | } 118 | 119 | #[test] 120 | fn iadd_small_test() { 121 | // Overflow check (single) 122 | // This should set all the internal data values to 0, the top 123 | // value to (1<<31), and the bottom value to (4>>1). 124 | // This is because the max_value + 1 leads to all 0s, we set the 125 | // topmost bit to 1. 126 | let mut x = Bigint { 127 | data: from_u32(&[4294967295]), 128 | }; 129 | x.iadd_small(5); 130 | assert_eq!(x.data, from_u32(&[4, 1])); 131 | 132 | // No overflow, single value 133 | let mut x = Bigint { 134 | data: from_u32(&[5]), 135 | }; 136 | x.iadd_small(7); 137 | assert_eq!(x.data, from_u32(&[12])); 138 | 139 | // Single carry, internal overflow 140 | let mut x = Bigint::from_u64(0x80000000FFFFFFFF); 141 | x.iadd_small(7); 142 | assert_eq!(x.data, from_u32(&[6, 0x80000001])); 143 | 144 | // Double carry, overflow 145 | let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF); 146 | x.iadd_small(7); 147 | assert_eq!(x.data, from_u32(&[6, 0, 1])); 148 | } 149 | 150 | #[test] 151 | fn imul_small_test() { 152 | // No overflow check, 1-int. 153 | let mut x = Bigint { 154 | data: from_u32(&[5]), 155 | }; 156 | x.imul_small(7); 157 | assert_eq!(x.data, from_u32(&[35])); 158 | 159 | // No overflow check, 2-ints. 160 | let mut x = Bigint::from_u64(0x4000000040000); 161 | x.imul_small(5); 162 | assert_eq!(x.data, from_u32(&[0x00140000, 0x140000])); 163 | 164 | // Overflow, 1 carry. 165 | let mut x = Bigint { 166 | data: from_u32(&[0x33333334]), 167 | }; 168 | x.imul_small(5); 169 | assert_eq!(x.data, from_u32(&[4, 1])); 170 | 171 | // Overflow, 1 carry, internal. 172 | let mut x = Bigint::from_u64(0x133333334); 173 | x.imul_small(5); 174 | assert_eq!(x.data, from_u32(&[4, 6])); 175 | 176 | // Overflow, 2 carries. 177 | let mut x = Bigint::from_u64(0x3333333333333334); 178 | x.imul_small(5); 179 | assert_eq!(x.data, from_u32(&[4, 0, 1])); 180 | } 181 | 182 | #[test] 183 | fn shl_test() { 184 | // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])` 185 | let mut big = Bigint { 186 | data: from_u32(&[0xD2210408]), 187 | }; 188 | big.ishl(5); 189 | assert_eq!(big.data, from_u32(&[0x44208100, 0x1A])); 190 | big.ishl(32); 191 | assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A])); 192 | big.ishl(27); 193 | assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408])); 194 | 195 | // 96-bits of previous pattern 196 | let mut big = Bigint { 197 | data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]), 198 | }; 199 | big.ishl(5); 200 | assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A])); 201 | big.ishl(32); 202 | assert_eq!( 203 | big.data, 204 | from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A]) 205 | ); 206 | big.ishl(27); 207 | assert_eq!( 208 | big.data, 209 | from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408]) 210 | ); 211 | } 212 | -------------------------------------------------------------------------------- /tests/lexical/num.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use crate::lexical::num::{AsPrimitive, Float, Integer, Number}; 4 | 5 | fn check_as_primitive(t: T) { 6 | let _: u32 = t.as_u32(); 7 | let _: u64 = t.as_u64(); 8 | let _: u128 = t.as_u128(); 9 | let _: usize = t.as_usize(); 10 | let _: f32 = t.as_f32(); 11 | let _: f64 = t.as_f64(); 12 | } 13 | 14 | #[test] 15 | fn as_primitive_test() { 16 | check_as_primitive(1u32); 17 | check_as_primitive(1u64); 18 | check_as_primitive(1u128); 19 | check_as_primitive(1usize); 20 | check_as_primitive(1f32); 21 | check_as_primitive(1f64); 22 | } 23 | 24 | fn check_number(x: T, y: T) { 25 | // Copy, partialeq, partialord 26 | let _ = x; 27 | assert!(x < y); 28 | assert!(x != y); 29 | 30 | // Operations 31 | let _ = y + x; 32 | 33 | // Conversions already tested. 34 | } 35 | 36 | #[test] 37 | fn number_test() { 38 | check_number(1u32, 5); 39 | check_number(1u64, 5); 40 | check_number(1u128, 5); 41 | check_number(1usize, 5); 42 | check_number(1f32, 5.0); 43 | check_number(1f64, 5.0); 44 | } 45 | 46 | fn check_integer(x: T) { 47 | // Bitwise operations 48 | let _ = x & T::ZERO; 49 | } 50 | 51 | #[test] 52 | fn integer_test() { 53 | check_integer(65u32); 54 | check_integer(65u64); 55 | check_integer(65u128); 56 | check_integer(65usize); 57 | } 58 | 59 | fn check_float(x: T) { 60 | // Check functions 61 | let _ = x.pow10(5); 62 | let _ = x.to_bits(); 63 | assert!(T::from_bits(x.to_bits()) == x); 64 | 65 | // Check properties 66 | let _ = x.to_bits() & T::EXPONENT_MASK; 67 | let _ = x.to_bits() & T::HIDDEN_BIT_MASK; 68 | let _ = x.to_bits() & T::MANTISSA_MASK; 69 | } 70 | 71 | #[test] 72 | fn float_test() { 73 | check_float(123f32); 74 | check_float(123f64); 75 | } 76 | -------------------------------------------------------------------------------- /tests/lexical/rounding.rs: -------------------------------------------------------------------------------- 1 | // Adapted from https://github.com/Alexhuszagh/rust-lexical. 2 | 3 | use crate::lexical::float::ExtendedFloat; 4 | use crate::lexical::num::Float; 5 | use crate::lexical::rounding::*; 6 | 7 | // MASKS 8 | 9 | #[test] 10 | fn lower_n_mask_test() { 11 | assert_eq!(lower_n_mask(0u64), 0b0); 12 | assert_eq!(lower_n_mask(1u64), 0b1); 13 | assert_eq!(lower_n_mask(2u64), 0b11); 14 | assert_eq!(lower_n_mask(10u64), 0b1111111111); 15 | assert_eq!(lower_n_mask(32u64), 0b11111111111111111111111111111111); 16 | } 17 | 18 | #[test] 19 | fn lower_n_halfway_test() { 20 | assert_eq!(lower_n_halfway(0u64), 0b0); 21 | assert_eq!(lower_n_halfway(1u64), 0b1); 22 | assert_eq!(lower_n_halfway(2u64), 0b10); 23 | assert_eq!(lower_n_halfway(10u64), 0b1000000000); 24 | assert_eq!(lower_n_halfway(32u64), 0b10000000000000000000000000000000); 25 | } 26 | 27 | #[test] 28 | fn nth_bit_test() { 29 | assert_eq!(nth_bit(0u64), 0b1); 30 | assert_eq!(nth_bit(1u64), 0b10); 31 | assert_eq!(nth_bit(2u64), 0b100); 32 | assert_eq!(nth_bit(10u64), 0b10000000000); 33 | assert_eq!(nth_bit(31u64), 0b10000000000000000000000000000000); 34 | } 35 | 36 | #[test] 37 | fn internal_n_mask_test() { 38 | assert_eq!(internal_n_mask(1u64, 0u64), 0b0); 39 | assert_eq!(internal_n_mask(1u64, 1u64), 0b1); 40 | assert_eq!(internal_n_mask(2u64, 1u64), 0b10); 41 | assert_eq!(internal_n_mask(4u64, 2u64), 0b1100); 42 | assert_eq!(internal_n_mask(10u64, 2u64), 0b1100000000); 43 | assert_eq!(internal_n_mask(10u64, 4u64), 0b1111000000); 44 | assert_eq!( 45 | internal_n_mask(32u64, 4u64), 46 | 0b11110000000000000000000000000000 47 | ); 48 | } 49 | 50 | // NEAREST ROUNDING 51 | 52 | #[test] 53 | fn round_nearest_test() { 54 | // Check exactly halfway (b'1100000') 55 | let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; 56 | let (above, halfway) = round_nearest(&mut fp, 6); 57 | assert!(!above); 58 | assert!(halfway); 59 | assert_eq!(fp.mant, 1); 60 | 61 | // Check above halfway (b'1100001') 62 | let mut fp = ExtendedFloat { mant: 0x61, exp: 0 }; 63 | let (above, halfway) = round_nearest(&mut fp, 6); 64 | assert!(above); 65 | assert!(!halfway); 66 | assert_eq!(fp.mant, 1); 67 | 68 | // Check below halfway (b'1011111') 69 | let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 }; 70 | let (above, halfway) = round_nearest(&mut fp, 6); 71 | assert!(!above); 72 | assert!(!halfway); 73 | assert_eq!(fp.mant, 1); 74 | } 75 | 76 | // DIRECTED ROUNDING 77 | 78 | #[test] 79 | fn round_downward_test() { 80 | // b0000000 81 | let mut fp = ExtendedFloat { mant: 0x00, exp: 0 }; 82 | round_downward(&mut fp, 6); 83 | assert_eq!(fp.mant, 0); 84 | 85 | // b1000000 86 | let mut fp = ExtendedFloat { mant: 0x40, exp: 0 }; 87 | round_downward(&mut fp, 6); 88 | assert_eq!(fp.mant, 1); 89 | 90 | // b1100000 91 | let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; 92 | round_downward(&mut fp, 6); 93 | assert_eq!(fp.mant, 1); 94 | 95 | // b1110000 96 | let mut fp = ExtendedFloat { mant: 0x70, exp: 0 }; 97 | round_downward(&mut fp, 6); 98 | assert_eq!(fp.mant, 1); 99 | } 100 | 101 | #[test] 102 | fn round_nearest_tie_even_test() { 103 | // Check round-up, halfway 104 | let mut fp = ExtendedFloat { mant: 0x60, exp: 0 }; 105 | round_nearest_tie_even(&mut fp, 6); 106 | assert_eq!(fp.mant, 2); 107 | 108 | // Check round-down, halfway 109 | let mut fp = ExtendedFloat { mant: 0x20, exp: 0 }; 110 | round_nearest_tie_even(&mut fp, 6); 111 | assert_eq!(fp.mant, 0); 112 | 113 | // Check round-up, above halfway 114 | let mut fp = ExtendedFloat { mant: 0x61, exp: 0 }; 115 | round_nearest_tie_even(&mut fp, 6); 116 | assert_eq!(fp.mant, 2); 117 | 118 | let mut fp = ExtendedFloat { mant: 0x21, exp: 0 }; 119 | round_nearest_tie_even(&mut fp, 6); 120 | assert_eq!(fp.mant, 1); 121 | 122 | // Check round-down, below halfway 123 | let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 }; 124 | round_nearest_tie_even(&mut fp, 6); 125 | assert_eq!(fp.mant, 1); 126 | 127 | let mut fp = ExtendedFloat { mant: 0x1F, exp: 0 }; 128 | round_nearest_tie_even(&mut fp, 6); 129 | assert_eq!(fp.mant, 0); 130 | } 131 | 132 | // HIGH-LEVEL 133 | 134 | #[test] 135 | fn round_to_float_test() { 136 | // Denormal 137 | let mut fp = ExtendedFloat { 138 | mant: 1 << 63, 139 | exp: f64::DENORMAL_EXPONENT - 15, 140 | }; 141 | round_to_float::(&mut fp, round_nearest_tie_even); 142 | assert_eq!(fp.mant, 1 << 48); 143 | assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); 144 | 145 | // Halfway, round-down (b'1000000000000000000000000000000000000000000000000000010000000000') 146 | let mut fp = ExtendedFloat { 147 | mant: 0x8000000000000400, 148 | exp: -63, 149 | }; 150 | round_to_float::(&mut fp, round_nearest_tie_even); 151 | assert_eq!(fp.mant, 1 << 52); 152 | assert_eq!(fp.exp, -52); 153 | 154 | // Halfway, round-up (b'1000000000000000000000000000000000000000000000000000110000000000') 155 | let mut fp = ExtendedFloat { 156 | mant: 0x8000000000000C00, 157 | exp: -63, 158 | }; 159 | round_to_float::(&mut fp, round_nearest_tie_even); 160 | assert_eq!(fp.mant, (1 << 52) + 2); 161 | assert_eq!(fp.exp, -52); 162 | 163 | // Above halfway 164 | let mut fp = ExtendedFloat { 165 | mant: 0x8000000000000401, 166 | exp: -63, 167 | }; 168 | round_to_float::(&mut fp, round_nearest_tie_even); 169 | assert_eq!(fp.mant, (1 << 52) + 1); 170 | assert_eq!(fp.exp, -52); 171 | 172 | let mut fp = ExtendedFloat { 173 | mant: 0x8000000000000C01, 174 | exp: -63, 175 | }; 176 | round_to_float::(&mut fp, round_nearest_tie_even); 177 | assert_eq!(fp.mant, (1 << 52) + 2); 178 | assert_eq!(fp.exp, -52); 179 | 180 | // Below halfway 181 | let mut fp = ExtendedFloat { 182 | mant: 0x80000000000003FF, 183 | exp: -63, 184 | }; 185 | round_to_float::(&mut fp, round_nearest_tie_even); 186 | assert_eq!(fp.mant, 1 << 52); 187 | assert_eq!(fp.exp, -52); 188 | 189 | let mut fp = ExtendedFloat { 190 | mant: 0x8000000000000BFF, 191 | exp: -63, 192 | }; 193 | round_to_float::(&mut fp, round_nearest_tie_even); 194 | assert_eq!(fp.mant, (1 << 52) + 1); 195 | assert_eq!(fp.exp, -52); 196 | } 197 | 198 | #[test] 199 | fn avoid_overflow_test() { 200 | // Avoid overflow, fails by 1 201 | let mut fp = ExtendedFloat { 202 | mant: 0xFFFFFFFFFFFF, 203 | exp: f64::MAX_EXPONENT + 5, 204 | }; 205 | avoid_overflow::(&mut fp); 206 | assert_eq!(fp.mant, 0xFFFFFFFFFFFF); 207 | assert_eq!(fp.exp, f64::MAX_EXPONENT + 5); 208 | 209 | // Avoid overflow, succeeds 210 | let mut fp = ExtendedFloat { 211 | mant: 0xFFFFFFFFFFFF, 212 | exp: f64::MAX_EXPONENT + 4, 213 | }; 214 | avoid_overflow::(&mut fp); 215 | assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); 216 | assert_eq!(fp.exp, f64::MAX_EXPONENT - 1); 217 | } 218 | 219 | #[test] 220 | fn round_to_native_test() { 221 | // Overflow 222 | let mut fp = ExtendedFloat { 223 | mant: 0xFFFFFFFFFFFF, 224 | exp: f64::MAX_EXPONENT + 4, 225 | }; 226 | round_to_native::(&mut fp, round_nearest_tie_even); 227 | assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0); 228 | assert_eq!(fp.exp, f64::MAX_EXPONENT - 1); 229 | 230 | // Need denormal 231 | let mut fp = ExtendedFloat { 232 | mant: 1, 233 | exp: f64::DENORMAL_EXPONENT + 48, 234 | }; 235 | round_to_native::(&mut fp, round_nearest_tie_even); 236 | assert_eq!(fp.mant, 1 << 48); 237 | assert_eq!(fp.exp, f64::DENORMAL_EXPONENT); 238 | 239 | // Halfway, round-down (b'10000000000000000000000000000000000000000000000000000100000') 240 | let mut fp = ExtendedFloat { 241 | mant: 0x400000000000020, 242 | exp: -58, 243 | }; 244 | round_to_native::(&mut fp, round_nearest_tie_even); 245 | assert_eq!(fp.mant, 1 << 52); 246 | assert_eq!(fp.exp, -52); 247 | 248 | // Halfway, round-up (b'10000000000000000000000000000000000000000000000000001100000') 249 | let mut fp = ExtendedFloat { 250 | mant: 0x400000000000060, 251 | exp: -58, 252 | }; 253 | round_to_native::(&mut fp, round_nearest_tie_even); 254 | assert_eq!(fp.mant, (1 << 52) + 2); 255 | assert_eq!(fp.exp, -52); 256 | 257 | // Above halfway 258 | let mut fp = ExtendedFloat { 259 | mant: 0x400000000000021, 260 | exp: -58, 261 | }; 262 | round_to_native::(&mut fp, round_nearest_tie_even); 263 | assert_eq!(fp.mant, (1 << 52) + 1); 264 | assert_eq!(fp.exp, -52); 265 | 266 | let mut fp = ExtendedFloat { 267 | mant: 0x400000000000061, 268 | exp: -58, 269 | }; 270 | round_to_native::(&mut fp, round_nearest_tie_even); 271 | assert_eq!(fp.mant, (1 << 52) + 2); 272 | assert_eq!(fp.exp, -52); 273 | 274 | // Below halfway 275 | let mut fp = ExtendedFloat { 276 | mant: 0x40000000000001F, 277 | exp: -58, 278 | }; 279 | round_to_native::(&mut fp, round_nearest_tie_even); 280 | assert_eq!(fp.mant, 1 << 52); 281 | assert_eq!(fp.exp, -52); 282 | 283 | let mut fp = ExtendedFloat { 284 | mant: 0x40000000000005F, 285 | exp: -58, 286 | }; 287 | round_to_native::(&mut fp, round_nearest_tie_even); 288 | assert_eq!(fp.mant, (1 << 52) + 1); 289 | assert_eq!(fp.exp, -52); 290 | 291 | // Underflow 292 | // Adapted from failures in strtod. 293 | let mut fp = ExtendedFloat { 294 | exp: -1139, 295 | mant: 18446744073709550712, 296 | }; 297 | round_to_native::(&mut fp, round_nearest_tie_even); 298 | assert_eq!(fp.mant, 0); 299 | assert_eq!(fp.exp, 0); 300 | 301 | let mut fp = ExtendedFloat { 302 | exp: -1139, 303 | mant: 18446744073709551460, 304 | }; 305 | round_to_native::(&mut fp, round_nearest_tie_even); 306 | assert_eq!(fp.mant, 0); 307 | assert_eq!(fp.exp, 0); 308 | 309 | let mut fp = ExtendedFloat { 310 | exp: -1138, 311 | mant: 9223372036854776103, 312 | }; 313 | round_to_native::(&mut fp, round_nearest_tie_even); 314 | assert_eq!(fp.mant, 1); 315 | assert_eq!(fp.exp, -1074); 316 | } 317 | -------------------------------------------------------------------------------- /tests/macros/mod.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_macro_rules)] 2 | 3 | macro_rules! json_str { 4 | ([]) => { 5 | "[]" 6 | }; 7 | ([ $e0:tt $(, $e:tt)* $(,)? ]) => { 8 | concat!("[", 9 | json_str!($e0), 10 | $(",", json_str!($e),)* 11 | "]") 12 | }; 13 | ({}) => { 14 | "{}" 15 | }; 16 | ({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => { 17 | concat!("{", 18 | stringify!($k0), ":", json_str!($v0), 19 | $(",", stringify!($k), ":", json_str!($v),)* 20 | "}") 21 | }; 22 | (($other:tt)) => { 23 | $other 24 | }; 25 | ($other:tt) => { 26 | stringify!($other) 27 | }; 28 | } 29 | 30 | macro_rules! pretty_str { 31 | ($json:tt) => { 32 | pretty_str_impl!("", $json) 33 | }; 34 | } 35 | 36 | macro_rules! pretty_str_impl { 37 | ($indent:expr, []) => { 38 | "[]" 39 | }; 40 | ($indent:expr, [ $e0:tt $(, $e:tt)* $(,)? ]) => { 41 | concat!("[\n ", 42 | $indent, pretty_str_impl!(concat!(" ", $indent), $e0), 43 | $(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)* 44 | "\n", $indent, "]") 45 | }; 46 | ($indent:expr, {}) => { 47 | "{}" 48 | }; 49 | ($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => { 50 | concat!("{\n ", 51 | $indent, stringify!($k0), ": ", pretty_str_impl!(concat!(" ", $indent), $v0), 52 | $(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)* 53 | "\n", $indent, "}") 54 | }; 55 | ($indent:expr, ($other:tt)) => { 56 | $other 57 | }; 58 | ($indent:expr, $other:tt) => { 59 | stringify!($other) 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /tests/map.rs: -------------------------------------------------------------------------------- 1 | use serde_json::{from_str, Map, Value}; 2 | 3 | #[test] 4 | fn test_preserve_order() { 5 | // Sorted order 6 | #[cfg(not(feature = "preserve_order"))] 7 | const EXPECTED: &[&str] = &["a", "b", "c"]; 8 | 9 | // Insertion order 10 | #[cfg(feature = "preserve_order")] 11 | const EXPECTED: &[&str] = &["b", "a", "c"]; 12 | 13 | let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); 14 | let keys: Vec<_> = v.as_object().unwrap().keys().collect(); 15 | assert_eq!(keys, EXPECTED); 16 | } 17 | 18 | #[test] 19 | #[cfg(feature = "preserve_order")] 20 | fn test_shift_insert() { 21 | let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); 22 | let val = v.as_object_mut().unwrap(); 23 | val.shift_insert(0, "d".to_owned(), Value::Null); 24 | 25 | let keys: Vec<_> = val.keys().collect(); 26 | assert_eq!(keys, &["d", "b", "a", "c"]); 27 | } 28 | 29 | #[test] 30 | fn test_append() { 31 | // Sorted order 32 | #[cfg(not(feature = "preserve_order"))] 33 | const EXPECTED: &[&str] = &["a", "b", "c"]; 34 | 35 | // Insertion order 36 | #[cfg(feature = "preserve_order")] 37 | const EXPECTED: &[&str] = &["b", "a", "c"]; 38 | 39 | let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); 40 | let val = v.as_object_mut().unwrap(); 41 | let mut m = Map::new(); 42 | m.append(val); 43 | let keys: Vec<_> = m.keys().collect(); 44 | 45 | assert_eq!(keys, EXPECTED); 46 | assert!(val.is_empty()); 47 | } 48 | 49 | #[test] 50 | fn test_retain() { 51 | let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); 52 | let val = v.as_object_mut().unwrap(); 53 | val.retain(|k, _| k.as_str() != "b"); 54 | 55 | let keys: Vec<_> = val.keys().collect(); 56 | assert_eq!(keys, &["a", "c"]); 57 | } 58 | -------------------------------------------------------------------------------- /tests/regression.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::elidable_lifetime_names, clippy::needless_lifetimes)] 2 | 3 | mod regression { 4 | automod::dir!("tests/regression"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/regression/issue1004.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "arbitrary_precision")] 2 | 3 | #[test] 4 | fn test() { 5 | let float = 5.55f32; 6 | let value = serde_json::to_value(float).unwrap(); 7 | let json = serde_json::to_string(&value).unwrap(); 8 | 9 | // If the f32 were cast to f64 by Value before serialization, then this 10 | // would incorrectly serialize as 5.550000190734863. 11 | assert_eq!(json, "5.55"); 12 | } 13 | -------------------------------------------------------------------------------- /tests/regression/issue520.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::float_cmp)] 2 | 3 | use serde_derive::{Deserialize, Serialize}; 4 | 5 | #[derive(Serialize, Deserialize, Debug)] 6 | #[serde(tag = "type", content = "data")] 7 | enum E { 8 | Float(f32), 9 | } 10 | 11 | #[test] 12 | fn test() { 13 | let e = E::Float(159.1); 14 | let v = serde_json::to_value(e).unwrap(); 15 | let e = serde_json::from_value::(v).unwrap(); 16 | 17 | match e { 18 | E::Float(f) => assert_eq!(f, 159.1), 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/regression/issue795.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::assertions_on_result_states)] 2 | 3 | use serde::de::{ 4 | Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor, 5 | }; 6 | use serde_json::json; 7 | use std::fmt; 8 | 9 | #[derive(Debug)] 10 | pub enum Enum { 11 | Variant { 12 | #[allow(dead_code)] 13 | x: u8, 14 | }, 15 | } 16 | 17 | impl<'de> Deserialize<'de> for Enum { 18 | fn deserialize(deserializer: D) -> Result 19 | where 20 | D: Deserializer<'de>, 21 | { 22 | struct EnumVisitor; 23 | 24 | impl<'de> Visitor<'de> for EnumVisitor { 25 | type Value = Enum; 26 | 27 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 28 | formatter.write_str("enum Enum") 29 | } 30 | 31 | fn visit_enum(self, data: A) -> Result 32 | where 33 | A: EnumAccess<'de>, 34 | { 35 | let (IgnoredAny, variant) = data.variant()?; 36 | variant.struct_variant(&["x"], self) 37 | } 38 | 39 | fn visit_map(self, mut data: A) -> Result 40 | where 41 | A: MapAccess<'de>, 42 | { 43 | let mut x = 0; 44 | if let Some((IgnoredAny, value)) = data.next_entry()? { 45 | x = value; 46 | } 47 | Ok(Enum::Variant { x }) 48 | } 49 | } 50 | 51 | deserializer.deserialize_enum("Enum", &["Variant"], EnumVisitor) 52 | } 53 | } 54 | 55 | #[test] 56 | fn test() { 57 | let s = r#" {"Variant":{"x":0,"y":0}} "#; 58 | assert!(serde_json::from_str::(s).is_err()); 59 | 60 | let j = json!({"Variant":{"x":0,"y":0}}); 61 | assert!(serde_json::from_value::(j).is_err()); 62 | } 63 | -------------------------------------------------------------------------------- /tests/regression/issue845.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757 2 | 3 | use serde::{Deserialize, Deserializer}; 4 | use std::fmt::{self, Display}; 5 | use std::marker::PhantomData; 6 | use std::str::FromStr; 7 | 8 | pub struct NumberVisitor { 9 | marker: PhantomData, 10 | } 11 | 12 | impl<'de, T> serde::de::Visitor<'de> for NumberVisitor 13 | where 14 | T: TryFrom + TryFrom + FromStr, 15 | >::Error: Display, 16 | >::Error: Display, 17 | ::Err: Display, 18 | { 19 | type Value = T; 20 | 21 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 22 | formatter.write_str("an integer or string") 23 | } 24 | 25 | fn visit_u64(self, v: u64) -> Result 26 | where 27 | E: serde::de::Error, 28 | { 29 | T::try_from(v).map_err(serde::de::Error::custom) 30 | } 31 | 32 | fn visit_i64(self, v: i64) -> Result 33 | where 34 | E: serde::de::Error, 35 | { 36 | T::try_from(v).map_err(serde::de::Error::custom) 37 | } 38 | 39 | fn visit_str(self, v: &str) -> Result 40 | where 41 | E: serde::de::Error, 42 | { 43 | v.parse().map_err(serde::de::Error::custom) 44 | } 45 | } 46 | 47 | fn deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result 48 | where 49 | D: Deserializer<'de>, 50 | T: TryFrom + TryFrom + FromStr, 51 | >::Error: Display, 52 | >::Error: Display, 53 | ::Err: Display, 54 | { 55 | deserializer.deserialize_any(NumberVisitor { 56 | marker: PhantomData, 57 | }) 58 | } 59 | 60 | #[derive(Deserialize, Debug)] 61 | pub struct Struct { 62 | #[serde(deserialize_with = "deserialize_integer_or_string")] 63 | #[allow(dead_code)] 64 | pub i: i64, 65 | } 66 | 67 | #[test] 68 | fn test() { 69 | let j = r#" {"i":100} "#; 70 | println!("{:?}", serde_json::from_str::(j).unwrap()); 71 | 72 | let j = r#" {"i":"100"} "#; 73 | println!("{:?}", serde_json::from_str::(j).unwrap()); 74 | } 75 | -------------------------------------------------------------------------------- /tests/regression/issue953.rs: -------------------------------------------------------------------------------- 1 | use serde_json::Value; 2 | 3 | #[test] 4 | fn test() { 5 | let x1 = serde_json::from_str::("18446744073709551615."); 6 | assert!(x1.is_err()); 7 | let x2 = serde_json::from_str::("18446744073709551616."); 8 | assert!(x2.is_err()); 9 | } 10 | -------------------------------------------------------------------------------- /tests/stream.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::assertions_on_result_states)] 2 | 3 | use serde_json::{json, Deserializer, Value}; 4 | 5 | // Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740 6 | #[rustfmt::skip] 7 | macro_rules! test_stream { 8 | ($data:expr, $ty:ty, |$stream:ident| $test:block) => { 9 | { 10 | let de = Deserializer::from_str($data); 11 | let mut $stream = de.into_iter::<$ty>(); 12 | assert_eq!($stream.byte_offset(), 0); 13 | $test 14 | } 15 | { 16 | let de = Deserializer::from_slice($data.as_bytes()); 17 | let mut $stream = de.into_iter::<$ty>(); 18 | assert_eq!($stream.byte_offset(), 0); 19 | $test 20 | } 21 | { 22 | let mut bytes = $data.as_bytes(); 23 | let de = Deserializer::from_reader(&mut bytes); 24 | let mut $stream = de.into_iter::<$ty>(); 25 | assert_eq!($stream.byte_offset(), 0); 26 | $test 27 | } 28 | }; 29 | } 30 | 31 | #[test] 32 | fn test_json_stream_newlines() { 33 | let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}"; 34 | 35 | test_stream!(data, Value, |stream| { 36 | assert_eq!(stream.next().unwrap().unwrap()["x"], 39); 37 | assert_eq!(stream.byte_offset(), 8); 38 | 39 | assert_eq!(stream.next().unwrap().unwrap()["x"], 40); 40 | assert_eq!(stream.byte_offset(), 17); 41 | 42 | assert_eq!(stream.next().unwrap().unwrap()["x"], 41); 43 | assert_eq!(stream.byte_offset(), 25); 44 | 45 | assert_eq!(stream.next().unwrap().unwrap()["x"], 42); 46 | assert_eq!(stream.byte_offset(), 34); 47 | 48 | assert!(stream.next().is_none()); 49 | assert_eq!(stream.byte_offset(), 34); 50 | }); 51 | } 52 | 53 | #[test] 54 | fn test_json_stream_trailing_whitespaces() { 55 | let data = "{\"x\":42} \t\n"; 56 | 57 | test_stream!(data, Value, |stream| { 58 | assert_eq!(stream.next().unwrap().unwrap()["x"], 42); 59 | assert_eq!(stream.byte_offset(), 8); 60 | 61 | assert!(stream.next().is_none()); 62 | assert_eq!(stream.byte_offset(), 11); 63 | }); 64 | } 65 | 66 | #[test] 67 | fn test_json_stream_truncated() { 68 | let data = "{\"x\":40}\n{\"x\":"; 69 | 70 | test_stream!(data, Value, |stream| { 71 | assert_eq!(stream.next().unwrap().unwrap()["x"], 40); 72 | assert_eq!(stream.byte_offset(), 8); 73 | 74 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 75 | assert_eq!(stream.byte_offset(), 9); 76 | }); 77 | } 78 | 79 | #[test] 80 | fn test_json_stream_truncated_decimal() { 81 | let data = "{\"x\":4."; 82 | 83 | test_stream!(data, Value, |stream| { 84 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 85 | assert_eq!(stream.byte_offset(), 0); 86 | }); 87 | } 88 | 89 | #[test] 90 | fn test_json_stream_truncated_negative() { 91 | let data = "{\"x\":-"; 92 | 93 | test_stream!(data, Value, |stream| { 94 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 95 | assert_eq!(stream.byte_offset(), 0); 96 | }); 97 | } 98 | 99 | #[test] 100 | fn test_json_stream_truncated_exponent() { 101 | let data = "{\"x\":4e"; 102 | 103 | test_stream!(data, Value, |stream| { 104 | assert!(stream.next().unwrap().unwrap_err().is_eof()); 105 | assert_eq!(stream.byte_offset(), 0); 106 | }); 107 | } 108 | 109 | #[test] 110 | fn test_json_stream_empty() { 111 | let data = ""; 112 | 113 | test_stream!(data, Value, |stream| { 114 | assert!(stream.next().is_none()); 115 | assert_eq!(stream.byte_offset(), 0); 116 | }); 117 | } 118 | 119 | #[test] 120 | fn test_json_stream_primitive() { 121 | let data = "{} true{}1[]\nfalse\"hey\"2 "; 122 | 123 | test_stream!(data, Value, |stream| { 124 | assert_eq!(stream.next().unwrap().unwrap(), json!({})); 125 | assert_eq!(stream.byte_offset(), 2); 126 | 127 | assert_eq!(stream.next().unwrap().unwrap(), true); 128 | assert_eq!(stream.byte_offset(), 7); 129 | 130 | assert_eq!(stream.next().unwrap().unwrap(), json!({})); 131 | assert_eq!(stream.byte_offset(), 9); 132 | 133 | assert_eq!(stream.next().unwrap().unwrap(), 1); 134 | assert_eq!(stream.byte_offset(), 10); 135 | 136 | assert_eq!(stream.next().unwrap().unwrap(), json!([])); 137 | assert_eq!(stream.byte_offset(), 12); 138 | 139 | assert_eq!(stream.next().unwrap().unwrap(), false); 140 | assert_eq!(stream.byte_offset(), 18); 141 | 142 | assert_eq!(stream.next().unwrap().unwrap(), "hey"); 143 | assert_eq!(stream.byte_offset(), 23); 144 | 145 | assert_eq!(stream.next().unwrap().unwrap(), 2); 146 | assert_eq!(stream.byte_offset(), 24); 147 | 148 | assert!(stream.next().is_none()); 149 | assert_eq!(stream.byte_offset(), 25); 150 | }); 151 | } 152 | 153 | #[test] 154 | fn test_json_stream_invalid_literal() { 155 | let data = "truefalse"; 156 | 157 | test_stream!(data, Value, |stream| { 158 | let second = stream.next().unwrap().unwrap_err(); 159 | assert_eq!(second.to_string(), "trailing characters at line 1 column 5"); 160 | }); 161 | } 162 | 163 | #[test] 164 | fn test_json_stream_invalid_number() { 165 | let data = "1true"; 166 | 167 | test_stream!(data, Value, |stream| { 168 | let second = stream.next().unwrap().unwrap_err(); 169 | assert_eq!(second.to_string(), "trailing characters at line 1 column 2"); 170 | }); 171 | } 172 | 173 | #[test] 174 | fn test_error() { 175 | let data = "true wrong false"; 176 | 177 | test_stream!(data, Value, |stream| { 178 | assert_eq!(stream.next().unwrap().unwrap(), true); 179 | assert!(stream.next().unwrap().is_err()); 180 | assert!(stream.next().is_none()); 181 | }); 182 | } 183 | -------------------------------------------------------------------------------- /tests/ui/missing_colon.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/missing_colon.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of macro invocation 2 | --> tests/ui/missing_colon.rs:4:5 3 | | 4 | 4 | json!({ "a" }); 5 | | ^^^^^^^^^^^^^^ missing tokens in macro arguments 6 | | 7 | note: while trying to match `@` 8 | --> src/macros.rs 9 | | 10 | | (@array [$($elems:expr,)*]) => { 11 | | ^ 12 | = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) 13 | -------------------------------------------------------------------------------- /tests/ui/missing_comma.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "1": "" "2": "" }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/missing_comma.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `"2"` 2 | --> tests/ui/missing_comma.rs:4:21 3 | | 4 | 4 | json!({ "1": "" "2": "" }); 5 | | -^^^ no rules expected this token in macro call 6 | | | 7 | | help: missing comma here 8 | | 9 | note: while trying to match `,` 10 | --> src/macros.rs 11 | | 12 | | ($e:expr , $($tt:tt)*) => {}; 13 | | ^ 14 | -------------------------------------------------------------------------------- /tests/ui/missing_value.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/missing_value.stderr: -------------------------------------------------------------------------------- 1 | error: unexpected end of macro invocation 2 | --> tests/ui/missing_value.rs:4:5 3 | | 4 | 4 | json!({ "a" : }); 5 | | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments 6 | | 7 | note: while trying to match `@` 8 | --> src/macros.rs 9 | | 10 | | (@array [$($elems:expr,)*]) => { 11 | | ^ 12 | = note: this error originates in the macro `$crate::json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info) 13 | -------------------------------------------------------------------------------- /tests/ui/not_found.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : x }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/not_found.stderr: -------------------------------------------------------------------------------- 1 | error[E0425]: cannot find value `x` in this scope 2 | --> tests/ui/not_found.rs:4:19 3 | | 4 | 4 | json!({ "a" : x }); 5 | | ^ not found in this scope 6 | -------------------------------------------------------------------------------- /tests/ui/parse_expr.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" : ~ }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/parse_expr.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `~` 2 | --> tests/ui/parse_expr.rs:4:19 3 | | 4 | 4 | json!({ "a" : ~ }); 5 | | ^ no rules expected this token in macro call 6 | | 7 | note: while trying to match meta-variable `$e:expr` 8 | --> src/macros.rs 9 | | 10 | | ($e:expr , $($tt:tt)*) => {}; 11 | | ^^^^^^^ 12 | -------------------------------------------------------------------------------- /tests/ui/parse_key.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "".s : true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/parse_key.stderr: -------------------------------------------------------------------------------- 1 | error[E0609]: no field `s` on type `&'static str` 2 | --> tests/ui/parse_key.rs:4:16 3 | | 4 | 4 | json!({ "".s : true }); 5 | | ^ unknown field 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_array_element.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!([ true => ]); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_array_element.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `=>` 2 | --> tests/ui/unexpected_after_array_element.rs:4:18 3 | | 4 | 4 | json!([ true => ]); 5 | | ^^ no rules expected this token in macro call 6 | | 7 | = note: while trying to match end of macro 8 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_map_entry.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "k": true => }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_after_map_entry.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `=>` 2 | --> tests/ui/unexpected_after_map_entry.rs:4:23 3 | | 4 | 4 | json!({ "k": true => }); 5 | | ^^ no rules expected this token in macro call 6 | | 7 | = note: while trying to match end of macro 8 | -------------------------------------------------------------------------------- /tests/ui/unexpected_colon.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ : true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_colon.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `:` 2 | --> tests/ui/unexpected_colon.rs:4:13 3 | | 4 | 4 | json!({ : true }); 5 | | ^ no rules expected this token in macro call 6 | | 7 | = note: while trying to match end of macro 8 | -------------------------------------------------------------------------------- /tests/ui/unexpected_comma.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | 3 | fn main() { 4 | json!({ "a" , "b": true }); 5 | } 6 | -------------------------------------------------------------------------------- /tests/ui/unexpected_comma.stderr: -------------------------------------------------------------------------------- 1 | error: no rules expected `,` 2 | --> tests/ui/unexpected_comma.rs:4:17 3 | | 4 | 4 | json!({ "a" , "b": true }); 5 | | ^ no rules expected this token in macro call 6 | | 7 | = note: while trying to match end of macro 8 | --------------------------------------------------------------------------------