Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
This commit is contained in:
1
vendor/serde_json/.cargo-checksum.json
vendored
Normal file
1
vendor/serde_json/.cargo-checksum.json
vendored
Normal file
File diff suppressed because one or more lines are too long
46
vendor/serde_json/CONTRIBUTING.md
vendored
Normal file
46
vendor/serde_json/CONTRIBUTING.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
# Contributing to Serde
|
||||
|
||||
Serde welcomes contribution from everyone in the form of suggestions, bug
|
||||
reports, pull requests, and feedback. This document gives some guidance if you
|
||||
are thinking of helping us.
|
||||
|
||||
## Submitting bug reports and feature requests
|
||||
|
||||
Serde development is spread across lots of repositories. In general, prefer to
|
||||
open issues against the main [serde-rs/serde] repository unless the topic is
|
||||
clearly specific to JSON.
|
||||
|
||||
[serde-rs/serde]: https://github.com/serde-rs/serde
|
||||
|
||||
When reporting a bug or asking for help, please include enough details so that
|
||||
the people helping you can reproduce the behavior you are seeing. For some tips
|
||||
on how to approach this, read about how to produce a [Minimal, Complete, and
|
||||
Verifiable example].
|
||||
|
||||
[Minimal, Complete, and Verifiable example]: https://stackoverflow.com/help/mcve
|
||||
|
||||
When making a feature request, please make it clear what problem you intend to
|
||||
solve with the feature, any ideas for how Serde could support solving that
|
||||
problem, any possible alternatives, and any disadvantages.
|
||||
|
||||
## Running the test suite
|
||||
|
||||
We encourage you to check that the test suite passes locally before submitting a
|
||||
pull request with your changes. If anything does not pass, typically it will be
|
||||
easier to iterate and fix it locally than waiting for the CI servers to run
|
||||
tests for you.
|
||||
|
||||
The test suite requires a nightly compiler.
|
||||
|
||||
```sh
|
||||
# Run the full test suite, including doc test and compile-tests
|
||||
cargo test
|
||||
```
|
||||
|
||||
## Conduct
|
||||
|
||||
In all Serde-related forums, we follow the [Rust Code of Conduct]. For
|
||||
escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com)
|
||||
instead of the Rust moderation team.
|
||||
|
||||
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
|
109
vendor/serde_json/Cargo.toml
vendored
Normal file
109
vendor/serde_json/Cargo.toml
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.56"
|
||||
name = "serde_json"
|
||||
version = "1.0.111"
|
||||
authors = [
|
||||
"Erick Tryzelaar <erick.tryzelaar@gmail.com>",
|
||||
"David Tolnay <dtolnay@gmail.com>",
|
||||
]
|
||||
description = "A JSON serialization file format"
|
||||
documentation = "https://docs.rs/serde_json"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"json",
|
||||
"serde",
|
||||
"serialization",
|
||||
]
|
||||
categories = [
|
||||
"encoding",
|
||||
"parser-implementations",
|
||||
"no-std",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/serde-rs/json"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [
|
||||
"raw_value",
|
||||
"unbounded_depth",
|
||||
]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
"--generate-link-to-definition",
|
||||
]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[package.metadata.playground]
|
||||
features = ["raw_value"]
|
||||
|
||||
[lib]
|
||||
doc-scrape-examples = false
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "2"
|
||||
optional = true
|
||||
|
||||
[dependencies.itoa]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.ryu]
|
||||
version = "1.0"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.194"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies.automod]
|
||||
version = "1.0.11"
|
||||
|
||||
[dev-dependencies.indoc]
|
||||
version = "2.0.2"
|
||||
|
||||
[dev-dependencies.ref-cast]
|
||||
version = "1.0.18"
|
||||
|
||||
[dev-dependencies.rustversion]
|
||||
version = "1.0.13"
|
||||
|
||||
[dev-dependencies.serde]
|
||||
version = "1.0.194"
|
||||
features = ["derive"]
|
||||
|
||||
[dev-dependencies.serde_bytes]
|
||||
version = "0.11.10"
|
||||
|
||||
[dev-dependencies.serde_derive]
|
||||
version = "1.0.166"
|
||||
|
||||
[dev-dependencies.serde_stacker]
|
||||
version = "0.1.8"
|
||||
|
||||
[dev-dependencies.trybuild]
|
||||
version = "1.0.81"
|
||||
features = ["diff"]
|
||||
|
||||
[features]
|
||||
alloc = ["serde/alloc"]
|
||||
arbitrary_precision = []
|
||||
default = ["std"]
|
||||
float_roundtrip = []
|
||||
preserve_order = [
|
||||
"indexmap",
|
||||
"std",
|
||||
]
|
||||
raw_value = []
|
||||
std = ["serde/std"]
|
||||
unbounded_depth = []
|
176
vendor/serde_json/LICENSE-APACHE
vendored
Normal file
176
vendor/serde_json/LICENSE-APACHE
vendored
Normal file
@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
23
vendor/serde_json/LICENSE-MIT
vendored
Normal file
23
vendor/serde_json/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
390
vendor/serde_json/README.md
vendored
Normal file
390
vendor/serde_json/README.md
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
# Serde JSON   [![Build Status]][actions] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc]
|
||||
|
||||
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master
|
||||
[actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster
|
||||
[Latest Version]: https://img.shields.io/crates/v/serde_json.svg
|
||||
[crates.io]: https://crates.io/crates/serde\_json
|
||||
[Rustc Version 1.36+]: https://img.shields.io/badge/rustc-1.36+-lightgray.svg
|
||||
[rustc]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html
|
||||
|
||||
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
|
||||
|
||||
---
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
```
|
||||
|
||||
You may be looking for:
|
||||
|
||||
- [JSON API documentation](https://docs.rs/serde_json)
|
||||
- [Serde API documentation](https://docs.rs/serde)
|
||||
- [Detailed documentation about Serde](https://serde.rs/)
|
||||
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
|
||||
- [Release notes](https://github.com/serde-rs/json/releases)
|
||||
|
||||
JSON is a ubiquitous open-standard format that uses human-readable text to
|
||||
transmit data objects consisting of key-value pairs.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "John Doe",
|
||||
"age": 43,
|
||||
"address": {
|
||||
"street": "10 Downing Street",
|
||||
"city": "London"
|
||||
},
|
||||
"phones": [
|
||||
"+44 1234567",
|
||||
"+44 2345678"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
There are three common ways that you might find yourself needing to work with
|
||||
JSON data in Rust.
|
||||
|
||||
- **As text data.** An unprocessed string of JSON data that you receive on an
|
||||
HTTP endpoint, read from a file, or prepare to send to a remote server.
|
||||
- **As an untyped or loosely typed representation.** Maybe you want to check
|
||||
that some JSON data is valid before passing it on, but without knowing the
|
||||
structure of what it contains. Or you want to do very basic manipulations
|
||||
like insert a key in a particular spot.
|
||||
- **As a strongly typed Rust data structure.** When you expect all or most of
|
||||
your data to conform to a particular structure and want to get real work done
|
||||
without JSON's loosey-goosey nature tripping you up.
|
||||
|
||||
Serde JSON provides efficient, flexible, safe ways of converting data between
|
||||
each of these representations.
|
||||
|
||||
## Operating on untyped JSON values
|
||||
|
||||
Any valid JSON data can be manipulated in the following recursive enum
|
||||
representation. This data structure is [`serde_json::Value`][value].
|
||||
|
||||
```rust
|
||||
enum Value {
|
||||
Null,
|
||||
Bool(bool),
|
||||
Number(Number),
|
||||
String(String),
|
||||
Array(Vec<Value>),
|
||||
Object(Map<String, Value>),
|
||||
}
|
||||
```
|
||||
|
||||
A string of JSON data can be parsed into a `serde_json::Value` by the
|
||||
[`serde_json::from_str`][from_str] function. There is also
|
||||
[`from_slice`][from_slice] for parsing from a byte slice &\[u8\] and
|
||||
[`from_reader`][from_reader] for parsing from any `io::Read` like a File or a
|
||||
TCP stream.
|
||||
|
||||
<div align="right">
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72" target="_blank">
|
||||
<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
```rust
|
||||
use serde_json::{Result, Value};
|
||||
|
||||
fn untyped_example() -> Result<()> {
|
||||
// Some JSON input data as a &str. Maybe this comes from the user.
|
||||
let data = r#"
|
||||
{
|
||||
"name": "John Doe",
|
||||
"age": 43,
|
||||
"phones": [
|
||||
"+44 1234567",
|
||||
"+44 2345678"
|
||||
]
|
||||
}"#;
|
||||
|
||||
// Parse the string of data into serde_json::Value.
|
||||
let v: Value = serde_json::from_str(data)?;
|
||||
|
||||
// Access parts of the data by indexing with square brackets.
|
||||
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
The result of square bracket indexing like `v["name"]` is a borrow of the data
|
||||
at that index, so the type is `&Value`. A JSON map can be indexed with string
|
||||
keys, while a JSON array can be indexed with integer keys. If the type of the
|
||||
data is not right for the type with which it is being indexed, or if a map does
|
||||
not contain the key being indexed, or if the index into a vector is out of
|
||||
bounds, the returned element is `Value::Null`.
|
||||
|
||||
When a `Value` is printed, it is printed as a JSON string. So in the code above,
|
||||
the output looks like `Please call "John Doe" at the number "+44 1234567"`. The
|
||||
quotation marks appear because `v["name"]` is a `&Value` containing a JSON
|
||||
string and its JSON representation is `"John Doe"`. Printing as a plain string
|
||||
without quotation marks involves converting from a JSON string to a Rust string
|
||||
with [`as_str()`] or avoiding the use of `Value` as described in the following
|
||||
section.
|
||||
|
||||
[`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str
|
||||
|
||||
The `Value` representation is sufficient for very basic tasks but can be tedious
|
||||
to work with for anything more significant. Error handling is verbose to
|
||||
implement correctly, for example imagine trying to detect the presence of
|
||||
unrecognized fields in the input data. The compiler is powerless to help you
|
||||
when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]`
|
||||
in one of the dozens of places it is used in your code.
|
||||
|
||||
## Parsing JSON as strongly typed data structures
|
||||
|
||||
Serde provides a powerful way of mapping JSON data into Rust data structures
|
||||
largely automatically.
|
||||
|
||||
<div align="right">
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=15cfab66d38ff8a15a9cf1d8d897ac68" target="_blank">
|
||||
<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
```rust
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Result;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Person {
|
||||
name: String,
|
||||
age: u8,
|
||||
phones: Vec<String>,
|
||||
}
|
||||
|
||||
fn typed_example() -> Result<()> {
|
||||
// Some JSON input data as a &str. Maybe this comes from the user.
|
||||
let data = r#"
|
||||
{
|
||||
"name": "John Doe",
|
||||
"age": 43,
|
||||
"phones": [
|
||||
"+44 1234567",
|
||||
"+44 2345678"
|
||||
]
|
||||
}"#;
|
||||
|
||||
// Parse the string of data into a Person object. This is exactly the
|
||||
// same function as the one that produced serde_json::Value above, but
|
||||
// now we are asking it for a Person as output.
|
||||
let p: Person = serde_json::from_str(data)?;
|
||||
|
||||
// Do things just like with any other Rust data structure.
|
||||
println!("Please call {} at the number {}", p.name, p.phones[0]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
This is the same `serde_json::from_str` function as before, but this time we
|
||||
assign the return value to a variable of type `Person` so Serde will
|
||||
automatically interpret the input data as a `Person` and produce informative
|
||||
error messages if the layout does not conform to what a `Person` is expected to
|
||||
look like.
|
||||
|
||||
Any type that implements Serde's `Deserialize` trait can be deserialized this
|
||||
way. This includes built-in Rust standard library types like `Vec<T>` and
|
||||
`HashMap<K, V>`, as well as any structs or enums annotated with
|
||||
`#[derive(Deserialize)]`.
|
||||
|
||||
Once we have `p` of type `Person`, our IDE and the Rust compiler can help us use
|
||||
it correctly like they do for any other Rust code. The IDE can autocomplete
|
||||
field names to prevent typos, which was impossible in the `serde_json::Value`
|
||||
representation. And the Rust compiler can check that when we write
|
||||
`p.phones[0]`, then `p.phones` is guaranteed to be a `Vec<String>` so indexing
|
||||
into it makes sense and produces a `String`.
|
||||
|
||||
The necessary setup for using Serde's derive macros is explained on the *[Using
|
||||
derive]* page of the Serde site.
|
||||
|
||||
[Using derive]: https://serde.rs/derive.html
|
||||
|
||||
## Constructing JSON values
|
||||
|
||||
Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
|
||||
objects with very natural JSON syntax.
|
||||
|
||||
<div align="right">
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=6ccafad431d72b62e77cc34c8e879b24" target="_blank">
|
||||
<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
```rust
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
// The type of `john` is `serde_json::Value`
|
||||
let john = json!({
|
||||
"name": "John Doe",
|
||||
"age": 43,
|
||||
"phones": [
|
||||
"+44 1234567",
|
||||
"+44 2345678"
|
||||
]
|
||||
});
|
||||
|
||||
println!("first phone number: {}", john["phones"][0]);
|
||||
|
||||
// Convert to a string of JSON and print it out
|
||||
println!("{}", john.to_string());
|
||||
}
|
||||
```
|
||||
|
||||
The `Value::to_string()` function converts a `serde_json::Value` into a `String`
|
||||
of JSON text.
|
||||
|
||||
One neat thing about the `json!` macro is that variables and expressions can be
|
||||
interpolated directly into the JSON value as you are building it. Serde will
|
||||
check at compile time that the value you are interpolating is able to be
|
||||
represented as JSON.
|
||||
|
||||
<div align="right">
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2" target="_blank">
|
||||
<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
```rust
|
||||
let full_name = "John Doe";
|
||||
let age_last_year = 42;
|
||||
|
||||
// The type of `john` is `serde_json::Value`
|
||||
let john = json!({
|
||||
"name": full_name,
|
||||
"age": age_last_year + 1,
|
||||
"phones": [
|
||||
format!("+44 {}", random_phone())
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
This is amazingly convenient, but we have the problem we had before with
|
||||
`Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON
|
||||
provides a better way of serializing strongly-typed data structures into JSON
|
||||
text.
|
||||
|
||||
## Creating JSON by serializing data structures
|
||||
|
||||
A data structure can be converted to a JSON string by
|
||||
[`serde_json::to_string`][to_string]. There is also
|
||||
[`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
|
||||
[`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
|
||||
such as a File or a TCP stream.
|
||||
|
||||
<div align="right">
|
||||
<a href="https://play.rust-lang.org/?edition=2018&gist=3472242a08ed2ff88a944f2a2283b0ee" target="_blank">
|
||||
<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
```rust
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Result;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Address {
|
||||
street: String,
|
||||
city: String,
|
||||
}
|
||||
|
||||
fn print_an_address() -> Result<()> {
|
||||
// Some data structure.
|
||||
let address = Address {
|
||||
street: "10 Downing Street".to_owned(),
|
||||
city: "London".to_owned(),
|
||||
};
|
||||
|
||||
// Serialize it to a JSON string.
|
||||
let j = serde_json::to_string(&address)?;
|
||||
|
||||
// Print, write to a file, or send to an HTTP server.
|
||||
println!("{}", j);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
Any type that implements Serde's `Serialize` trait can be serialized this way.
|
||||
This includes built-in Rust standard library types like `Vec<T>` and `HashMap<K,
|
||||
V>`, as well as any structs or enums annotated with `#[derive(Serialize)]`.
|
||||
|
||||
## Performance
|
||||
|
||||
It is fast. You should expect in the ballpark of 500 to 1000 megabytes per
|
||||
second deserialization and 600 to 900 megabytes per second serialization,
|
||||
depending on the characteristics of your data. This is competitive with the
|
||||
fastest C and C++ JSON libraries or even 30% faster for many use cases.
|
||||
Benchmarks live in the [serde-rs/json-benchmark] repo.
|
||||
|
||||
[serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark
|
||||
|
||||
## Getting help
|
||||
|
||||
Serde is one of the most widely used Rust libraries, so any place that
|
||||
Rustaceans congregate will be able to help you out. For chat, consider trying
|
||||
the [#rust-questions] or [#rust-beginners] channels of the unofficial community
|
||||
Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
|
||||
[#beginners] channels of the official Rust Project Discord (invite:
|
||||
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
|
||||
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
|
||||
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
|
||||
[Discourse forum][discourse]. It's acceptable to file a support issue in this
|
||||
repo, but they tend not to get as many eyes as any of the above and may get
|
||||
closed without a response after some time.
|
||||
|
||||
[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
|
||||
[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
|
||||
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
|
||||
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
|
||||
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
|
||||
[/r/rust]: https://www.reddit.com/r/rust
|
||||
[discourse]: https://users.rust-lang.org
|
||||
|
||||
## No-std support
|
||||
|
||||
As long as there is a memory allocator, it is possible to use serde_json without
|
||||
the rest of the Rust standard library. Disable the default "std" feature and
|
||||
enable the "alloc" feature:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||
```
|
||||
|
||||
For JSON support in Serde without a memory allocator, please see the
|
||||
[`serde-json-core`] crate.
|
||||
|
||||
[`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
|
||||
|
||||
[value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html
|
||||
[from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html
|
||||
[from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html
|
||||
[from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html
|
||||
[to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html
|
||||
[to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html
|
||||
[to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html
|
||||
[macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html
|
||||
|
||||
<br>
|
||||
|
||||
#### License
|
||||
|
||||
<sup>
|
||||
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
|
||||
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
|
||||
</sup>
|
||||
|
||||
<br>
|
||||
|
||||
<sub>
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
|
||||
be dual licensed as above, without any additional terms or conditions.
|
||||
</sub>
|
17
vendor/serde_json/build.rs
vendored
Normal file
17
vendor/serde_json/build.rs
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
// Decide ideal limb width for arithmetic in the float parser. Refer to
|
||||
// src/lexical/math.rs for where this has an effect.
|
||||
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
match target_arch.as_str() {
|
||||
"aarch64" | "mips64" | "powerpc64" | "x86_64" | "loongarch64" => {
|
||||
println!("cargo:rustc-cfg=limb_width_64");
|
||||
}
|
||||
_ => {
|
||||
println!("cargo:rustc-cfg=limb_width_32");
|
||||
}
|
||||
}
|
||||
}
|
2679
vendor/serde_json/src/de.rs
vendored
Normal file
2679
vendor/serde_json/src/de.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
516
vendor/serde_json/src/error.rs
vendored
Normal file
516
vendor/serde_json/src/error.rs
vendored
Normal file
@ -0,0 +1,516 @@
|
||||
//! When serializing or deserializing JSON goes wrong.
|
||||
|
||||
use crate::io;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::{String, ToString};
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::result;
|
||||
use core::str::FromStr;
|
||||
use serde::{de, ser};
|
||||
#[cfg(feature = "std")]
|
||||
use std::error;
|
||||
#[cfg(feature = "std")]
|
||||
use std::io::ErrorKind;
|
||||
|
||||
/// This type represents all possible errors that can occur when serializing or
|
||||
/// deserializing JSON data.
|
||||
pub struct Error {
|
||||
/// This `Box` allows us to keep the size of `Error` as small as possible. A
|
||||
/// larger `Error` type was substantially slower due to all the functions
|
||||
/// that pass around `Result<T, Error>`.
|
||||
err: Box<ErrorImpl>,
|
||||
}
|
||||
|
||||
/// Alias for a `Result` with the error type `serde_json::Error`.
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
impl Error {
|
||||
/// One-based line number at which the error was detected.
|
||||
///
|
||||
/// Characters in the first line of the input (before the first newline
|
||||
/// character) are in line 1.
|
||||
pub fn line(&self) -> usize {
|
||||
self.err.line
|
||||
}
|
||||
|
||||
/// One-based column number at which the error was detected.
|
||||
///
|
||||
/// The first character in the input and any characters immediately
|
||||
/// following a newline character are in column 1.
|
||||
///
|
||||
/// Note that errors may occur in column 0, for example if a read from an
|
||||
/// I/O stream fails immediately following a previously read newline
|
||||
/// character.
|
||||
pub fn column(&self) -> usize {
|
||||
self.err.column
|
||||
}
|
||||
|
||||
/// Categorizes the cause of this error.
|
||||
///
|
||||
/// - `Category::Io` - failure to read or write bytes on an I/O stream
|
||||
/// - `Category::Syntax` - input that is not syntactically valid JSON
|
||||
/// - `Category::Data` - input data that is semantically incorrect
|
||||
/// - `Category::Eof` - unexpected end of the input data
|
||||
pub fn classify(&self) -> Category {
|
||||
match self.err.code {
|
||||
ErrorCode::Message(_) => Category::Data,
|
||||
ErrorCode::Io(_) => Category::Io,
|
||||
ErrorCode::EofWhileParsingList
|
||||
| ErrorCode::EofWhileParsingObject
|
||||
| ErrorCode::EofWhileParsingString
|
||||
| ErrorCode::EofWhileParsingValue => Category::Eof,
|
||||
ErrorCode::ExpectedColon
|
||||
| ErrorCode::ExpectedListCommaOrEnd
|
||||
| ErrorCode::ExpectedObjectCommaOrEnd
|
||||
| ErrorCode::ExpectedSomeIdent
|
||||
| ErrorCode::ExpectedSomeValue
|
||||
| ErrorCode::ExpectedDoubleQuote
|
||||
| ErrorCode::InvalidEscape
|
||||
| ErrorCode::InvalidNumber
|
||||
| ErrorCode::NumberOutOfRange
|
||||
| ErrorCode::InvalidUnicodeCodePoint
|
||||
| ErrorCode::ControlCharacterWhileParsingString
|
||||
| ErrorCode::KeyMustBeAString
|
||||
| ErrorCode::ExpectedNumericKey
|
||||
| ErrorCode::FloatKeyMustBeFinite
|
||||
| ErrorCode::LoneLeadingSurrogateInHexEscape
|
||||
| ErrorCode::TrailingComma
|
||||
| ErrorCode::TrailingCharacters
|
||||
| ErrorCode::UnexpectedEndOfHexEscape
|
||||
| ErrorCode::RecursionLimitExceeded => Category::Syntax,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this error was caused by a failure to read or write
|
||||
/// bytes on an I/O stream.
|
||||
pub fn is_io(&self) -> bool {
|
||||
self.classify() == Category::Io
|
||||
}
|
||||
|
||||
/// Returns true if this error was caused by input that was not
|
||||
/// syntactically valid JSON.
|
||||
pub fn is_syntax(&self) -> bool {
|
||||
self.classify() == Category::Syntax
|
||||
}
|
||||
|
||||
/// Returns true if this error was caused by input data that was
|
||||
/// semantically incorrect.
|
||||
///
|
||||
/// For example, JSON containing a number is semantically incorrect when the
|
||||
/// type being deserialized into holds a String.
|
||||
pub fn is_data(&self) -> bool {
|
||||
self.classify() == Category::Data
|
||||
}
|
||||
|
||||
/// Returns true if this error was caused by prematurely reaching the end of
|
||||
/// the input data.
|
||||
///
|
||||
/// Callers that process streaming input may be interested in retrying the
|
||||
/// deserialization once more data is available.
|
||||
pub fn is_eof(&self) -> bool {
|
||||
self.classify() == Category::Eof
|
||||
}
|
||||
|
||||
/// The kind reported by the underlying standard library I/O error, if this
|
||||
/// error was caused by a failure to read or write bytes on an I/O stream.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
/// use std::io::{self, ErrorKind, Read};
|
||||
/// use std::process;
|
||||
///
|
||||
/// struct ReaderThatWillTimeOut<'a>(&'a [u8]);
|
||||
///
|
||||
/// impl<'a> Read for ReaderThatWillTimeOut<'a> {
|
||||
/// fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
/// if self.0.is_empty() {
|
||||
/// Err(io::Error::new(ErrorKind::TimedOut, "timed out"))
|
||||
/// } else {
|
||||
/// self.0.read(buf)
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// let reader = ReaderThatWillTimeOut(br#" {"k": "#);
|
||||
///
|
||||
/// let _: Value = match serde_json::from_reader(reader) {
|
||||
/// Ok(value) => value,
|
||||
/// Err(error) => {
|
||||
/// if error.io_error_kind() == Some(ErrorKind::TimedOut) {
|
||||
/// // Maybe this application needs to retry certain kinds of errors.
|
||||
///
|
||||
/// # return;
|
||||
/// } else {
|
||||
/// eprintln!("error: {}", error);
|
||||
/// process::exit(1);
|
||||
/// }
|
||||
/// }
|
||||
/// };
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(feature = "std")]
|
||||
pub fn io_error_kind(&self) -> Option<ErrorKind> {
|
||||
if let ErrorCode::Io(io_error) = &self.err.code {
|
||||
Some(io_error.kind())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Categorizes the cause of a `serde_json::Error`.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Category {
|
||||
/// The error was caused by a failure to read or write bytes on an I/O
|
||||
/// stream.
|
||||
Io,
|
||||
|
||||
/// The error was caused by input that was not syntactically valid JSON.
|
||||
Syntax,
|
||||
|
||||
/// The error was caused by input data that was semantically incorrect.
|
||||
///
|
||||
/// For example, JSON containing a number is semantically incorrect when the
|
||||
/// type being deserialized into holds a String.
|
||||
Data,
|
||||
|
||||
/// The error was caused by prematurely reaching the end of the input data.
|
||||
///
|
||||
/// Callers that process streaming input may be interested in retrying the
|
||||
/// deserialization once more data is available.
|
||||
Eof,
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[allow(clippy::fallible_impl_from)]
|
||||
impl From<Error> for io::Error {
|
||||
/// Convert a `serde_json::Error` into an `io::Error`.
|
||||
///
|
||||
/// JSON syntax and data errors are turned into `InvalidData` I/O errors.
|
||||
/// EOF errors are turned into `UnexpectedEof` I/O errors.
|
||||
///
|
||||
/// ```
|
||||
/// use std::io;
|
||||
///
|
||||
/// enum MyError {
|
||||
/// Io(io::Error),
|
||||
/// Json(serde_json::Error),
|
||||
/// }
|
||||
///
|
||||
/// impl From<serde_json::Error> for MyError {
|
||||
/// fn from(err: serde_json::Error) -> MyError {
|
||||
/// use serde_json::error::Category;
|
||||
/// match err.classify() {
|
||||
/// Category::Io => {
|
||||
/// MyError::Io(err.into())
|
||||
/// }
|
||||
/// Category::Syntax | Category::Data | Category::Eof => {
|
||||
/// MyError::Json(err)
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
fn from(j: Error) -> Self {
|
||||
if let ErrorCode::Io(err) = j.err.code {
|
||||
err
|
||||
} else {
|
||||
match j.classify() {
|
||||
Category::Io => unreachable!(),
|
||||
Category::Syntax | Category::Data => io::Error::new(ErrorKind::InvalidData, j),
|
||||
Category::Eof => io::Error::new(ErrorKind::UnexpectedEof, j),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ErrorImpl {
|
||||
code: ErrorCode,
|
||||
line: usize,
|
||||
column: usize,
|
||||
}
|
||||
|
||||
pub(crate) enum ErrorCode {
|
||||
/// Catchall for syntax error messages
|
||||
Message(Box<str>),
|
||||
|
||||
/// Some I/O error occurred while serializing or deserializing.
|
||||
Io(io::Error),
|
||||
|
||||
/// EOF while parsing a list.
|
||||
EofWhileParsingList,
|
||||
|
||||
/// EOF while parsing an object.
|
||||
EofWhileParsingObject,
|
||||
|
||||
/// EOF while parsing a string.
|
||||
EofWhileParsingString,
|
||||
|
||||
/// EOF while parsing a JSON value.
|
||||
EofWhileParsingValue,
|
||||
|
||||
/// Expected this character to be a `':'`.
|
||||
ExpectedColon,
|
||||
|
||||
/// Expected this character to be either a `','` or a `']'`.
|
||||
ExpectedListCommaOrEnd,
|
||||
|
||||
/// Expected this character to be either a `','` or a `'}'`.
|
||||
ExpectedObjectCommaOrEnd,
|
||||
|
||||
/// Expected to parse either a `true`, `false`, or a `null`.
|
||||
ExpectedSomeIdent,
|
||||
|
||||
/// Expected this character to start a JSON value.
|
||||
ExpectedSomeValue,
|
||||
|
||||
/// Expected this character to be a `"`.
|
||||
ExpectedDoubleQuote,
|
||||
|
||||
/// Invalid hex escape code.
|
||||
InvalidEscape,
|
||||
|
||||
/// Invalid number.
|
||||
InvalidNumber,
|
||||
|
||||
/// Number is bigger than the maximum value of its type.
|
||||
NumberOutOfRange,
|
||||
|
||||
/// Invalid unicode code point.
|
||||
InvalidUnicodeCodePoint,
|
||||
|
||||
/// Control character found while parsing a string.
|
||||
ControlCharacterWhileParsingString,
|
||||
|
||||
/// Object key is not a string.
|
||||
KeyMustBeAString,
|
||||
|
||||
/// Contents of key were supposed to be a number.
|
||||
ExpectedNumericKey,
|
||||
|
||||
/// Object key is a non-finite float value.
|
||||
FloatKeyMustBeFinite,
|
||||
|
||||
/// Lone leading surrogate in hex escape.
|
||||
LoneLeadingSurrogateInHexEscape,
|
||||
|
||||
/// JSON has a comma after the last value in an array or map.
|
||||
TrailingComma,
|
||||
|
||||
/// JSON has non-whitespace trailing characters after the value.
|
||||
TrailingCharacters,
|
||||
|
||||
/// Unexpected end of hex escape.
|
||||
UnexpectedEndOfHexEscape,
|
||||
|
||||
/// Encountered nesting of JSON maps and arrays more than 128 layers deep.
|
||||
RecursionLimitExceeded,
|
||||
}
|
||||
|
||||
impl Error {
|
||||
#[cold]
|
||||
pub(crate) fn syntax(code: ErrorCode, line: usize, column: usize) -> Self {
|
||||
Error {
|
||||
err: Box::new(ErrorImpl { code, line, column }),
|
||||
}
|
||||
}
|
||||
|
||||
// Not public API. Should be pub(crate).
|
||||
//
|
||||
// Update `eager_json` crate when this function changes.
|
||||
#[doc(hidden)]
|
||||
#[cold]
|
||||
pub fn io(error: io::Error) -> Self {
|
||||
Error {
|
||||
err: Box::new(ErrorImpl {
|
||||
code: ErrorCode::Io(error),
|
||||
line: 0,
|
||||
column: 0,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub(crate) fn fix_position<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(ErrorCode) -> Error,
|
||||
{
|
||||
if self.err.line == 0 {
|
||||
f(self.err.code)
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ErrorCode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
ErrorCode::Message(msg) => f.write_str(msg),
|
||||
ErrorCode::Io(err) => Display::fmt(err, f),
|
||||
ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"),
|
||||
ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"),
|
||||
ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"),
|
||||
ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"),
|
||||
ErrorCode::ExpectedColon => f.write_str("expected `:`"),
|
||||
ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"),
|
||||
ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"),
|
||||
ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"),
|
||||
ErrorCode::ExpectedSomeValue => f.write_str("expected value"),
|
||||
ErrorCode::ExpectedDoubleQuote => f.write_str("expected `\"`"),
|
||||
ErrorCode::InvalidEscape => f.write_str("invalid escape"),
|
||||
ErrorCode::InvalidNumber => f.write_str("invalid number"),
|
||||
ErrorCode::NumberOutOfRange => f.write_str("number out of range"),
|
||||
ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"),
|
||||
ErrorCode::ControlCharacterWhileParsingString => {
|
||||
f.write_str("control character (\\u0000-\\u001F) found while parsing a string")
|
||||
}
|
||||
ErrorCode::KeyMustBeAString => f.write_str("key must be a string"),
|
||||
ErrorCode::ExpectedNumericKey => {
|
||||
f.write_str("invalid value: expected key to be a number in quotes")
|
||||
}
|
||||
ErrorCode::FloatKeyMustBeFinite => {
|
||||
f.write_str("float key must be finite (got NaN or +/-inf)")
|
||||
}
|
||||
ErrorCode::LoneLeadingSurrogateInHexEscape => {
|
||||
f.write_str("lone leading surrogate in hex escape")
|
||||
}
|
||||
ErrorCode::TrailingComma => f.write_str("trailing comma"),
|
||||
ErrorCode::TrailingCharacters => f.write_str("trailing characters"),
|
||||
ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"),
|
||||
ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::de::StdError for Error {
|
||||
#[cfg(feature = "std")]
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
match &self.err.code {
|
||||
ErrorCode::Io(err) => err.source(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&*self.err, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ErrorImpl {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.line == 0 {
|
||||
Display::fmt(&self.code, f)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"{} at line {} column {}",
|
||||
self.code, self.line, self.column
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove two layers of verbosity from the debug representation. Humans often
|
||||
// end up seeing this representation because it is what unwrap() shows.
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Error({:?}, line: {}, column: {})",
|
||||
self.err.code.to_string(),
|
||||
self.err.line,
|
||||
self.err.column
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl de::Error for Error {
|
||||
#[cold]
|
||||
fn custom<T: Display>(msg: T) -> Error {
|
||||
make_error(msg.to_string())
|
||||
}
|
||||
|
||||
#[cold]
|
||||
fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
|
||||
if let de::Unexpected::Unit = unexp {
|
||||
Error::custom(format_args!("invalid type: null, expected {}", exp))
|
||||
} else {
|
||||
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ser::Error for Error {
|
||||
#[cold]
|
||||
fn custom<T: Display>(msg: T) -> Error {
|
||||
make_error(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
// Parse our own error message that looks like "{} at line {} column {}" to work
|
||||
// around erased-serde round-tripping the error through de::Error::custom.
|
||||
fn make_error(mut msg: String) -> Error {
|
||||
let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0));
|
||||
Error {
|
||||
err: Box::new(ErrorImpl {
|
||||
code: ErrorCode::Message(msg.into_boxed_str()),
|
||||
line,
|
||||
column,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> {
|
||||
let start_of_suffix = match msg.rfind(" at line ") {
|
||||
Some(index) => index,
|
||||
None => return None,
|
||||
};
|
||||
|
||||
// Find start and end of line number.
|
||||
let start_of_line = start_of_suffix + " at line ".len();
|
||||
let mut end_of_line = start_of_line;
|
||||
while starts_with_digit(&msg[end_of_line..]) {
|
||||
end_of_line += 1;
|
||||
}
|
||||
|
||||
if !msg[end_of_line..].starts_with(" column ") {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Find start and end of column number.
|
||||
let start_of_column = end_of_line + " column ".len();
|
||||
let mut end_of_column = start_of_column;
|
||||
while starts_with_digit(&msg[end_of_column..]) {
|
||||
end_of_column += 1;
|
||||
}
|
||||
|
||||
if end_of_column < msg.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Parse numbers.
|
||||
let line = match usize::from_str(&msg[start_of_line..end_of_line]) {
|
||||
Ok(line) => line,
|
||||
Err(_) => return None,
|
||||
};
|
||||
let column = match usize::from_str(&msg[start_of_column..end_of_column]) {
|
||||
Ok(column) => column,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
msg.truncate(start_of_suffix);
|
||||
Some((line, column))
|
||||
}
|
||||
|
||||
fn starts_with_digit(slice: &str) -> bool {
|
||||
match slice.as_bytes().first() {
|
||||
None => false,
|
||||
Some(&byte) => byte >= b'0' && byte <= b'9',
|
||||
}
|
||||
}
|
1
vendor/serde_json/src/features_check/error.rs
vendored
Normal file
1
vendor/serde_json/src/features_check/error.rs
vendored
Normal file
@ -0,0 +1 @@
|
||||
"serde_json requires that either `std` (default) or `alloc` feature is enabled"
|
13
vendor/serde_json/src/features_check/mod.rs
vendored
Normal file
13
vendor/serde_json/src/features_check/mod.rs
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
//! Shows a user-friendly compiler error on incompatible selected features.
|
||||
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! hide_from_rustfmt {
|
||||
($mod:item) => {
|
||||
$mod
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(any(feature = "std", feature = "alloc")))]
|
||||
hide_from_rustfmt! {
|
||||
mod error;
|
||||
}
|
79
vendor/serde_json/src/io/core.rs
vendored
Normal file
79
vendor/serde_json/src/io/core.rs
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
//! Reimplements core logic and types from `std::io` in an `alloc`-friendly
|
||||
//! fashion.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::{self, Display};
|
||||
use core::result;
|
||||
|
||||
pub enum ErrorKind {
|
||||
Other,
|
||||
}
|
||||
|
||||
// I/O errors can never occur in no-std mode. All our no-std I/O implementations
|
||||
// are infallible.
|
||||
pub struct Error;
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error {
|
||||
Error
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
pub trait Write {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize>;
|
||||
|
||||
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||
// All our Write impls in no_std mode always write the whole buffer in
|
||||
// one call infallibly.
|
||||
let result = self.write(buf);
|
||||
debug_assert!(result.is_ok());
|
||||
debug_assert_eq!(result.unwrap_or(0), buf.len());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()>;
|
||||
}
|
||||
|
||||
impl<W: Write> Write for &mut W {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
(*self).write(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||
(*self).write_all(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
(*self).flush()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Vec<u8> {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize> {
|
||||
self.extend_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||
self.extend_from_slice(buf);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
20
vendor/serde_json/src/io/mod.rs
vendored
Normal file
20
vendor/serde_json/src/io/mod.rs
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
//! A tiny, `no_std`-friendly facade around `std::io`.
|
||||
//! Reexports types from `std` when available; otherwise reimplements and
|
||||
//! provides some of the core logic.
|
||||
//!
|
||||
//! The main reason that `std::io` hasn't found itself reexported as part of
|
||||
//! the `core` crate is the `std::io::{Read, Write}` traits' reliance on
|
||||
//! `std::io::Error`, which may contain internally a heap-allocated `Box<Error>`
|
||||
//! and/or now relying on OS-specific `std::backtrace::Backtrace`.
|
||||
|
||||
pub use self::imp::{Error, ErrorKind, Result, Write};
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[path = "core.rs"]
|
||||
mod imp;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::io as imp;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use std::io::{Bytes, Read};
|
70
vendor/serde_json/src/iter.rs
vendored
Normal file
70
vendor/serde_json/src/iter.rs
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
use crate::io;
|
||||
|
||||
pub struct LineColIterator<I> {
|
||||
iter: I,
|
||||
|
||||
/// Index of the current line. Characters in the first line of the input
|
||||
/// (before the first newline character) are in line 1.
|
||||
line: usize,
|
||||
|
||||
/// Index of the current column. The first character in the input and any
|
||||
/// characters immediately following a newline character are in column 1.
|
||||
/// The column is 0 immediately after a newline character has been read.
|
||||
col: usize,
|
||||
|
||||
/// Byte offset of the start of the current line. This is the sum of lengths
|
||||
/// of all previous lines. Keeping track of things this way allows efficient
|
||||
/// computation of the current line, column, and byte offset while only
|
||||
/// updating one of the counters in `next()` in the common case.
|
||||
start_of_line: usize,
|
||||
}
|
||||
|
||||
impl<I> LineColIterator<I>
|
||||
where
|
||||
I: Iterator<Item = io::Result<u8>>,
|
||||
{
|
||||
pub fn new(iter: I) -> LineColIterator<I> {
|
||||
LineColIterator {
|
||||
iter,
|
||||
line: 1,
|
||||
col: 0,
|
||||
start_of_line: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn line(&self) -> usize {
|
||||
self.line
|
||||
}
|
||||
|
||||
pub fn col(&self) -> usize {
|
||||
self.col
|
||||
}
|
||||
|
||||
pub fn byte_offset(&self) -> usize {
|
||||
self.start_of_line + self.col
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> Iterator for LineColIterator<I>
|
||||
where
|
||||
I: Iterator<Item = io::Result<u8>>,
|
||||
{
|
||||
type Item = io::Result<u8>;
|
||||
|
||||
fn next(&mut self) -> Option<io::Result<u8>> {
|
||||
match self.iter.next() {
|
||||
None => None,
|
||||
Some(Ok(b'\n')) => {
|
||||
self.start_of_line += self.col + 1;
|
||||
self.line += 1;
|
||||
self.col = 0;
|
||||
Some(Ok(b'\n'))
|
||||
}
|
||||
Some(Ok(c)) => {
|
||||
self.col += 1;
|
||||
Some(Ok(c))
|
||||
}
|
||||
Some(Err(e)) => Some(Err(e)),
|
||||
}
|
||||
}
|
||||
}
|
196
vendor/serde_json/src/lexical/algorithm.rs
vendored
Normal file
196
vendor/serde_json/src/lexical/algorithm.rs
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Algorithms to efficiently convert strings to floats.
|
||||
|
||||
use super::bhcomp::*;
|
||||
use super::cached::*;
|
||||
use super::errors::*;
|
||||
use super::float::ExtendedFloat;
|
||||
use super::num::*;
|
||||
use super::small_powers::*;
|
||||
|
||||
// FAST
|
||||
// ----
|
||||
|
||||
/// Convert mantissa to exact value for a non-base2 power.
|
||||
///
|
||||
/// Returns the resulting float and if the value can be represented exactly.
|
||||
pub(crate) fn fast_path<F>(mantissa: u64, exponent: i32) -> Option<F>
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// `mantissa >> (F::MANTISSA_SIZE+1) != 0` effectively checks if the
|
||||
// value has a no bits above the hidden bit, which is what we want.
|
||||
let (min_exp, max_exp) = F::exponent_limit();
|
||||
let shift_exp = F::mantissa_limit();
|
||||
let mantissa_size = F::MANTISSA_SIZE + 1;
|
||||
if mantissa == 0 {
|
||||
Some(F::ZERO)
|
||||
} else if mantissa >> mantissa_size != 0 {
|
||||
// Would require truncation of the mantissa.
|
||||
None
|
||||
} else if exponent == 0 {
|
||||
// 0 exponent, same as value, exact representation.
|
||||
let float = F::as_cast(mantissa);
|
||||
Some(float)
|
||||
} else if exponent >= min_exp && exponent <= max_exp {
|
||||
// Value can be exactly represented, return the value.
|
||||
// Do not use powi, since powi can incrementally introduce
|
||||
// error.
|
||||
let float = F::as_cast(mantissa);
|
||||
Some(float.pow10(exponent))
|
||||
} else if exponent >= 0 && exponent <= max_exp + shift_exp {
|
||||
// Check to see if we have a disguised fast-path, where the
|
||||
// number of digits in the mantissa is very small, but and
|
||||
// so digits can be shifted from the exponent to the mantissa.
|
||||
// https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
|
||||
let small_powers = POW10_64;
|
||||
let shift = exponent - max_exp;
|
||||
let power = small_powers[shift as usize];
|
||||
|
||||
// Compute the product of the power, if it overflows,
|
||||
// prematurely return early, otherwise, if we didn't overshoot,
|
||||
// we can get an exact value.
|
||||
let value = match mantissa.checked_mul(power) {
|
||||
None => return None,
|
||||
Some(value) => value,
|
||||
};
|
||||
if value >> mantissa_size != 0 {
|
||||
None
|
||||
} else {
|
||||
// Use powi, since it's correct, and faster on
|
||||
// the fast-path.
|
||||
let float = F::as_cast(value);
|
||||
Some(float.pow10(max_exp))
|
||||
}
|
||||
} else {
|
||||
// Cannot be exactly represented, exponent too small or too big,
|
||||
// would require truncation.
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// MODERATE
|
||||
// --------
|
||||
|
||||
/// Multiply the floating-point by the exponent.
|
||||
///
|
||||
/// Multiply by pre-calculated powers of the base, modify the extended-
|
||||
/// float, and return if new value and if the value can be represented
|
||||
/// accurately.
|
||||
fn multiply_exponent_extended<F>(fp: &mut ExtendedFloat, exponent: i32, truncated: bool) -> bool
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
let powers = ExtendedFloat::get_powers();
|
||||
let exponent = exponent.saturating_add(powers.bias);
|
||||
let small_index = exponent % powers.step;
|
||||
let large_index = exponent / powers.step;
|
||||
if exponent < 0 {
|
||||
// Guaranteed underflow (assign 0).
|
||||
fp.mant = 0;
|
||||
true
|
||||
} else if large_index as usize >= powers.large.len() {
|
||||
// Overflow (assign infinity)
|
||||
fp.mant = 1 << 63;
|
||||
fp.exp = 0x7FF;
|
||||
true
|
||||
} else {
|
||||
// Within the valid exponent range, multiply by the large and small
|
||||
// exponents and return the resulting value.
|
||||
|
||||
// Track errors to as a factor of unit in last-precision.
|
||||
let mut errors: u32 = 0;
|
||||
if truncated {
|
||||
errors += u64::error_halfscale();
|
||||
}
|
||||
|
||||
// Multiply by the small power.
|
||||
// Check if we can directly multiply by an integer, if not,
|
||||
// use extended-precision multiplication.
|
||||
match fp
|
||||
.mant
|
||||
.overflowing_mul(powers.get_small_int(small_index as usize))
|
||||
{
|
||||
// Overflow, multiplication unsuccessful, go slow path.
|
||||
(_, true) => {
|
||||
fp.normalize();
|
||||
fp.imul(&powers.get_small(small_index as usize));
|
||||
errors += u64::error_halfscale();
|
||||
}
|
||||
// No overflow, multiplication successful.
|
||||
(mant, false) => {
|
||||
fp.mant = mant;
|
||||
fp.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply by the large power
|
||||
fp.imul(&powers.get_large(large_index as usize));
|
||||
if errors > 0 {
|
||||
errors += 1;
|
||||
}
|
||||
errors += u64::error_halfscale();
|
||||
|
||||
// Normalize the floating point (and the errors).
|
||||
let shift = fp.normalize();
|
||||
errors <<= shift;
|
||||
|
||||
u64::error_is_accurate::<F>(errors, fp)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a precise native float using an intermediate extended-precision float.
|
||||
///
|
||||
/// Return the float approximation and if the value can be accurately
|
||||
/// represented with mantissa bits of precision.
|
||||
#[inline]
|
||||
pub(crate) fn moderate_path<F>(
|
||||
mantissa: u64,
|
||||
exponent: i32,
|
||||
truncated: bool,
|
||||
) -> (ExtendedFloat, bool)
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: mantissa,
|
||||
exp: 0,
|
||||
};
|
||||
let valid = multiply_exponent_extended::<F>(&mut fp, exponent, truncated);
|
||||
(fp, valid)
|
||||
}
|
||||
|
||||
// FALLBACK
|
||||
// --------
|
||||
|
||||
/// Fallback path when the fast path does not work.
|
||||
///
|
||||
/// Uses the moderate path, if applicable, otherwise, uses the slow path
|
||||
/// as required.
|
||||
pub(crate) fn fallback_path<F>(
|
||||
integer: &[u8],
|
||||
fraction: &[u8],
|
||||
mantissa: u64,
|
||||
exponent: i32,
|
||||
mantissa_exponent: i32,
|
||||
truncated: bool,
|
||||
) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Moderate path (use an extended 80-bit representation).
|
||||
let (fp, valid) = moderate_path::<F>(mantissa, mantissa_exponent, truncated);
|
||||
if valid {
|
||||
return fp.into_float::<F>();
|
||||
}
|
||||
|
||||
// Slow path, fast path didn't work.
|
||||
let b = fp.into_downward_float::<F>();
|
||||
if b.is_special() {
|
||||
// We have a non-finite number, we get to leave early.
|
||||
b
|
||||
} else {
|
||||
bhcomp(b, integer, fraction, exponent)
|
||||
}
|
||||
}
|
218
vendor/serde_json/src/lexical/bhcomp.rs
vendored
Normal file
218
vendor/serde_json/src/lexical/bhcomp.rs
vendored
Normal file
@ -0,0 +1,218 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Compare the mantissa to the halfway representation of the float.
|
||||
//!
|
||||
//! Compares the actual significant digits of the mantissa to the
|
||||
//! theoretical digits from `b+h`, scaled into the proper range.
|
||||
|
||||
use super::bignum::*;
|
||||
use super::digit::*;
|
||||
use super::exponent::*;
|
||||
use super::float::*;
|
||||
use super::math::*;
|
||||
use super::num::*;
|
||||
use super::rounding::*;
|
||||
use core::{cmp, mem};
|
||||
|
||||
// MANTISSA
|
||||
|
||||
/// Parse the full mantissa into a big integer.
|
||||
///
|
||||
/// Max digits is the maximum number of digits plus one.
|
||||
fn parse_mantissa<F>(integer: &[u8], fraction: &[u8]) -> Bigint
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Main loop
|
||||
let small_powers = POW10_LIMB;
|
||||
let step = small_powers.len() - 2;
|
||||
let max_digits = F::MAX_DIGITS - 1;
|
||||
let mut counter = 0;
|
||||
let mut value: Limb = 0;
|
||||
let mut i: usize = 0;
|
||||
let mut result = Bigint::default();
|
||||
|
||||
// Iteratively process all the data in the mantissa.
|
||||
for &digit in integer.iter().chain(fraction) {
|
||||
// We've parsed the max digits using small values, add to bignum
|
||||
if counter == step {
|
||||
result.imul_small(small_powers[counter]);
|
||||
result.iadd_small(value);
|
||||
counter = 0;
|
||||
value = 0;
|
||||
}
|
||||
|
||||
value *= 10;
|
||||
value += as_limb(to_digit(digit).unwrap());
|
||||
|
||||
i += 1;
|
||||
counter += 1;
|
||||
if i == max_digits {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We will always have a remainder, as long as we entered the loop
|
||||
// once, or counter % step is 0.
|
||||
if counter != 0 {
|
||||
result.imul_small(small_powers[counter]);
|
||||
result.iadd_small(value);
|
||||
}
|
||||
|
||||
// If we have any remaining digits after the last value, we need
|
||||
// to add a 1 after the rest of the array, it doesn't matter where,
|
||||
// just move it up. This is good for the worst-possible float
|
||||
// representation. We also need to return an index.
|
||||
// Since we already trimmed trailing zeros, we know there has
|
||||
// to be a non-zero digit if there are any left.
|
||||
if i < integer.len() + fraction.len() {
|
||||
result.imul_small(10);
|
||||
result.iadd_small(1);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
// FLOAT OPS
|
||||
|
||||
/// Calculate `b` from a a representation of `b` as a float.
|
||||
#[inline]
|
||||
pub(super) fn b_extended<F: Float>(f: F) -> ExtendedFloat {
|
||||
ExtendedFloat::from_float(f)
|
||||
}
|
||||
|
||||
/// Calculate `b+h` from a a representation of `b` as a float.
|
||||
#[inline]
|
||||
pub(super) fn bh_extended<F: Float>(f: F) -> ExtendedFloat {
|
||||
// None of these can overflow.
|
||||
let b = b_extended(f);
|
||||
ExtendedFloat {
|
||||
mant: (b.mant << 1) + 1,
|
||||
exp: b.exp - 1,
|
||||
}
|
||||
}
|
||||
|
||||
// ROUNDING
|
||||
|
||||
/// Custom round-nearest, tie-event algorithm for bhcomp.
|
||||
#[inline]
|
||||
fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32, is_truncated: bool) {
|
||||
let (mut is_above, mut is_halfway) = round_nearest(fp, shift);
|
||||
if is_halfway && is_truncated {
|
||||
is_above = true;
|
||||
is_halfway = false;
|
||||
}
|
||||
tie_even(fp, is_above, is_halfway);
|
||||
}
|
||||
|
||||
// BHCOMP
|
||||
|
||||
/// Calculate the mantissa for a big integer with a positive exponent.
|
||||
fn large_atof<F>(mantissa: Bigint, exponent: i32) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
let bits = mem::size_of::<u64>() * 8;
|
||||
|
||||
// Simple, we just need to multiply by the power of the radix.
|
||||
// Now, we can calculate the mantissa and the exponent from this.
|
||||
// The binary exponent is the binary exponent for the mantissa
|
||||
// shifted to the hidden bit.
|
||||
let mut bigmant = mantissa;
|
||||
bigmant.imul_pow10(exponent as u32);
|
||||
|
||||
// Get the exact representation of the float from the big integer.
|
||||
let (mant, is_truncated) = bigmant.hi64();
|
||||
let exp = bigmant.bit_length() as i32 - bits as i32;
|
||||
let mut fp = ExtendedFloat { mant, exp };
|
||||
fp.round_to_native::<F, _>(|fp, shift| round_nearest_tie_even(fp, shift, is_truncated));
|
||||
into_float(fp)
|
||||
}
|
||||
|
||||
/// Calculate the mantissa for a big integer with a negative exponent.
|
||||
///
|
||||
/// This invokes the comparison with `b+h`.
|
||||
fn small_atof<F>(mantissa: Bigint, exponent: i32, f: F) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Get the significant digits and radix exponent for the real digits.
|
||||
let mut real_digits = mantissa;
|
||||
let real_exp = exponent;
|
||||
debug_assert!(real_exp < 0);
|
||||
|
||||
// Get the significant digits and the binary exponent for `b+h`.
|
||||
let theor = bh_extended(f);
|
||||
let mut theor_digits = Bigint::from_u64(theor.mant);
|
||||
let theor_exp = theor.exp;
|
||||
|
||||
// We need to scale the real digits and `b+h` digits to be the same
|
||||
// order. We currently have `real_exp`, in `radix`, that needs to be
|
||||
// shifted to `theor_digits` (since it is negative), and `theor_exp`
|
||||
// to either `theor_digits` or `real_digits` as a power of 2 (since it
|
||||
// may be positive or negative). Try to remove as many powers of 2
|
||||
// as possible. All values are relative to `theor_digits`, that is,
|
||||
// reflect the power you need to multiply `theor_digits` by.
|
||||
|
||||
// Can remove a power-of-two, since the radix is 10.
|
||||
// Both are on opposite-sides of equation, can factor out a
|
||||
// power of two.
|
||||
//
|
||||
// Example: 10^-10, 2^-10 -> ( 0, 10, 0)
|
||||
// Example: 10^-10, 2^-15 -> (-5, 10, 0)
|
||||
// Example: 10^-10, 2^-5 -> ( 5, 10, 0)
|
||||
// Example: 10^-10, 2^5 -> (15, 10, 0)
|
||||
let binary_exp = theor_exp - real_exp;
|
||||
let halfradix_exp = -real_exp;
|
||||
let radix_exp = 0;
|
||||
|
||||
// Carry out our multiplication.
|
||||
if halfradix_exp != 0 {
|
||||
theor_digits.imul_pow5(halfradix_exp as u32);
|
||||
}
|
||||
if radix_exp != 0 {
|
||||
theor_digits.imul_pow10(radix_exp as u32);
|
||||
}
|
||||
if binary_exp > 0 {
|
||||
theor_digits.imul_pow2(binary_exp as u32);
|
||||
} else if binary_exp < 0 {
|
||||
real_digits.imul_pow2(-binary_exp as u32);
|
||||
}
|
||||
|
||||
// Compare real digits to theoretical digits and round the float.
|
||||
match real_digits.compare(&theor_digits) {
|
||||
cmp::Ordering::Greater => f.next_positive(),
|
||||
cmp::Ordering::Less => f,
|
||||
cmp::Ordering::Equal => f.round_positive_even(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the exact value of the float.
|
||||
///
|
||||
/// Note: fraction must not have trailing zeros.
|
||||
pub(crate) fn bhcomp<F>(b: F, integer: &[u8], mut fraction: &[u8], exponent: i32) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Calculate the number of integer digits and use that to determine
|
||||
// where the significant digits start in the fraction.
|
||||
let integer_digits = integer.len();
|
||||
let fraction_digits = fraction.len();
|
||||
let digits_start = if integer_digits == 0 {
|
||||
let start = fraction.iter().take_while(|&x| *x == b'0').count();
|
||||
fraction = &fraction[start..];
|
||||
start
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let sci_exp = scientific_exponent(exponent, integer_digits, digits_start);
|
||||
let count = F::MAX_DIGITS.min(integer_digits + fraction_digits - digits_start);
|
||||
let scaled_exponent = sci_exp + 1 - count as i32;
|
||||
|
||||
let mantissa = parse_mantissa::<F>(integer, fraction);
|
||||
if scaled_exponent >= 0 {
|
||||
large_atof(mantissa, scaled_exponent)
|
||||
} else {
|
||||
small_atof(mantissa, scaled_exponent, b)
|
||||
}
|
||||
}
|
33
vendor/serde_json/src/lexical/bignum.rs
vendored
Normal file
33
vendor/serde_json/src/lexical/bignum.rs
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Big integer type definition.
|
||||
|
||||
use super::math::*;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
/// Storage for a big integer type.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub(crate) struct Bigint {
|
||||
/// Internal storage for the Bigint, in little-endian order.
|
||||
pub(crate) data: Vec<Limb>,
|
||||
}
|
||||
|
||||
impl Default for Bigint {
|
||||
fn default() -> Self {
|
||||
Bigint {
|
||||
data: Vec::with_capacity(20),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Math for Bigint {
|
||||
#[inline]
|
||||
fn data(&self) -> &Vec<Limb> {
|
||||
&self.data
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn data_mut(&mut self) -> &mut Vec<Limb> {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
82
vendor/serde_json/src/lexical/cached.rs
vendored
Normal file
82
vendor/serde_json/src/lexical/cached.rs
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Cached powers trait for extended-precision floats.
|
||||
|
||||
use super::cached_float80;
|
||||
use super::float::ExtendedFloat;
|
||||
|
||||
// POWERS
|
||||
|
||||
/// Precalculated powers that uses two-separate arrays for memory-efficiency.
|
||||
#[doc(hidden)]
|
||||
pub(crate) struct ExtendedFloatArray {
|
||||
// Pre-calculated mantissa for the powers.
|
||||
pub mant: &'static [u64],
|
||||
// Pre-calculated binary exponents for the powers.
|
||||
pub exp: &'static [i32],
|
||||
}
|
||||
|
||||
/// Allow indexing of values without bounds checking
|
||||
impl ExtendedFloatArray {
|
||||
#[inline]
|
||||
pub fn get_extended_float(&self, index: usize) -> ExtendedFloat {
|
||||
let mant = self.mant[index];
|
||||
let exp = self.exp[index];
|
||||
ExtendedFloat { mant, exp }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.mant.len()
|
||||
}
|
||||
}
|
||||
|
||||
// MODERATE PATH POWERS
|
||||
|
||||
/// Precalculated powers of base N for the moderate path.
|
||||
#[doc(hidden)]
|
||||
pub(crate) struct ModeratePathPowers {
|
||||
// Pre-calculated small powers.
|
||||
pub small: ExtendedFloatArray,
|
||||
// Pre-calculated large powers.
|
||||
pub large: ExtendedFloatArray,
|
||||
/// Pre-calculated small powers as 64-bit integers
|
||||
pub small_int: &'static [u64],
|
||||
// Step between large powers and number of small powers.
|
||||
pub step: i32,
|
||||
// Exponent bias for the large powers.
|
||||
pub bias: i32,
|
||||
}
|
||||
|
||||
/// Allow indexing of values without bounds checking
|
||||
impl ModeratePathPowers {
|
||||
#[inline]
|
||||
pub fn get_small(&self, index: usize) -> ExtendedFloat {
|
||||
self.small.get_extended_float(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_large(&self, index: usize) -> ExtendedFloat {
|
||||
self.large.get_extended_float(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_small_int(&self, index: usize) -> u64 {
|
||||
self.small_int[index]
|
||||
}
|
||||
}
|
||||
|
||||
// CACHED EXTENDED POWERS
|
||||
|
||||
/// Cached powers as a trait for a floating-point type.
|
||||
pub(crate) trait ModeratePathCache {
|
||||
/// Get cached powers.
|
||||
fn get_powers() -> &'static ModeratePathPowers;
|
||||
}
|
||||
|
||||
impl ModeratePathCache for ExtendedFloat {
|
||||
#[inline]
|
||||
fn get_powers() -> &'static ModeratePathPowers {
|
||||
cached_float80::get_powers()
|
||||
}
|
||||
}
|
206
vendor/serde_json/src/lexical/cached_float80.rs
vendored
Normal file
206
vendor/serde_json/src/lexical/cached_float80.rs
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Cached exponents for basen values with 80-bit extended floats.
|
||||
//!
|
||||
//! Exact versions of base**n as an extended-precision float, with both
|
||||
//! large and small powers. Use the large powers to minimize the amount
|
||||
//! of compounded error.
|
||||
//!
|
||||
//! These values were calculated using Python, using the arbitrary-precision
|
||||
//! integer to calculate exact extended-representation of each value.
|
||||
//! These values are all normalized.
|
||||
|
||||
use super::cached::{ExtendedFloatArray, ModeratePathPowers};
|
||||
|
||||
// LOW-LEVEL
|
||||
// ---------
|
||||
|
||||
// BASE10
|
||||
|
||||
const BASE10_SMALL_MANTISSA: [u64; 10] = [
|
||||
9223372036854775808, // 10^0
|
||||
11529215046068469760, // 10^1
|
||||
14411518807585587200, // 10^2
|
||||
18014398509481984000, // 10^3
|
||||
11258999068426240000, // 10^4
|
||||
14073748835532800000, // 10^5
|
||||
17592186044416000000, // 10^6
|
||||
10995116277760000000, // 10^7
|
||||
13743895347200000000, // 10^8
|
||||
17179869184000000000, // 10^9
|
||||
];
|
||||
const BASE10_SMALL_EXPONENT: [i32; 10] = [
|
||||
-63, // 10^0
|
||||
-60, // 10^1
|
||||
-57, // 10^2
|
||||
-54, // 10^3
|
||||
-50, // 10^4
|
||||
-47, // 10^5
|
||||
-44, // 10^6
|
||||
-40, // 10^7
|
||||
-37, // 10^8
|
||||
-34, // 10^9
|
||||
];
|
||||
const BASE10_LARGE_MANTISSA: [u64; 66] = [
|
||||
11555125961253852697, // 10^-350
|
||||
13451937075301367670, // 10^-340
|
||||
15660115838168849784, // 10^-330
|
||||
18230774251475056848, // 10^-320
|
||||
10611707258198326947, // 10^-310
|
||||
12353653155963782858, // 10^-300
|
||||
14381545078898527261, // 10^-290
|
||||
16742321987285426889, // 10^-280
|
||||
9745314011399999080, // 10^-270
|
||||
11345038669416679861, // 10^-260
|
||||
13207363278391631158, // 10^-250
|
||||
15375394465392026070, // 10^-240
|
||||
17899314949046850752, // 10^-230
|
||||
10418772551374772303, // 10^-220
|
||||
12129047596099288555, // 10^-210
|
||||
14120069793541087484, // 10^-200
|
||||
16437924692338667210, // 10^-190
|
||||
9568131466127621947, // 10^-180
|
||||
11138771039116687545, // 10^-170
|
||||
12967236152753102995, // 10^-160
|
||||
15095849699286165408, // 10^-150
|
||||
17573882009934360870, // 10^-140
|
||||
10229345649675443343, // 10^-130
|
||||
11908525658859223294, // 10^-120
|
||||
13863348470604074297, // 10^-110
|
||||
16139061738043178685, // 10^-100
|
||||
9394170331095332911, // 10^-90
|
||||
10936253623915059621, // 10^-80
|
||||
12731474852090538039, // 10^-70
|
||||
14821387422376473014, // 10^-60
|
||||
17254365866976409468, // 10^-50
|
||||
10043362776618689222, // 10^-40
|
||||
11692013098647223345, // 10^-30
|
||||
13611294676837538538, // 10^-20
|
||||
15845632502852867518, // 10^-10
|
||||
9223372036854775808, // 10^0
|
||||
10737418240000000000, // 10^10
|
||||
12500000000000000000, // 10^20
|
||||
14551915228366851806, // 10^30
|
||||
16940658945086006781, // 10^40
|
||||
9860761315262647567, // 10^50
|
||||
11479437019748901445, // 10^60
|
||||
13363823550460978230, // 10^70
|
||||
15557538194652854267, // 10^80
|
||||
18111358157653424735, // 10^90
|
||||
10542197943230523224, // 10^100
|
||||
12272733663244316382, // 10^110
|
||||
14287342391028437277, // 10^120
|
||||
16632655625031838749, // 10^130
|
||||
9681479787123295682, // 10^140
|
||||
11270725851789228247, // 10^150
|
||||
13120851772591970218, // 10^160
|
||||
15274681817498023410, // 10^170
|
||||
17782069995880619867, // 10^180
|
||||
10350527006597618960, // 10^190
|
||||
12049599325514420588, // 10^200
|
||||
14027579833653779454, // 10^210
|
||||
16330252207878254650, // 10^220
|
||||
9505457831475799117, // 10^230
|
||||
11065809325636130661, // 10^240
|
||||
12882297539194266616, // 10^250
|
||||
14996968138956309548, // 10^260
|
||||
17458768723248864463, // 10^270
|
||||
10162340898095201970, // 10^280
|
||||
11830521861667747109, // 10^290
|
||||
13772540099066387756, // 10^300
|
||||
];
|
||||
const BASE10_LARGE_EXPONENT: [i32; 66] = [
|
||||
-1226, // 10^-350
|
||||
-1193, // 10^-340
|
||||
-1160, // 10^-330
|
||||
-1127, // 10^-320
|
||||
-1093, // 10^-310
|
||||
-1060, // 10^-300
|
||||
-1027, // 10^-290
|
||||
-994, // 10^-280
|
||||
-960, // 10^-270
|
||||
-927, // 10^-260
|
||||
-894, // 10^-250
|
||||
-861, // 10^-240
|
||||
-828, // 10^-230
|
||||
-794, // 10^-220
|
||||
-761, // 10^-210
|
||||
-728, // 10^-200
|
||||
-695, // 10^-190
|
||||
-661, // 10^-180
|
||||
-628, // 10^-170
|
||||
-595, // 10^-160
|
||||
-562, // 10^-150
|
||||
-529, // 10^-140
|
||||
-495, // 10^-130
|
||||
-462, // 10^-120
|
||||
-429, // 10^-110
|
||||
-396, // 10^-100
|
||||
-362, // 10^-90
|
||||
-329, // 10^-80
|
||||
-296, // 10^-70
|
||||
-263, // 10^-60
|
||||
-230, // 10^-50
|
||||
-196, // 10^-40
|
||||
-163, // 10^-30
|
||||
-130, // 10^-20
|
||||
-97, // 10^-10
|
||||
-63, // 10^0
|
||||
-30, // 10^10
|
||||
3, // 10^20
|
||||
36, // 10^30
|
||||
69, // 10^40
|
||||
103, // 10^50
|
||||
136, // 10^60
|
||||
169, // 10^70
|
||||
202, // 10^80
|
||||
235, // 10^90
|
||||
269, // 10^100
|
||||
302, // 10^110
|
||||
335, // 10^120
|
||||
368, // 10^130
|
||||
402, // 10^140
|
||||
435, // 10^150
|
||||
468, // 10^160
|
||||
501, // 10^170
|
||||
534, // 10^180
|
||||
568, // 10^190
|
||||
601, // 10^200
|
||||
634, // 10^210
|
||||
667, // 10^220
|
||||
701, // 10^230
|
||||
734, // 10^240
|
||||
767, // 10^250
|
||||
800, // 10^260
|
||||
833, // 10^270
|
||||
867, // 10^280
|
||||
900, // 10^290
|
||||
933, // 10^300
|
||||
];
|
||||
const BASE10_SMALL_INT_POWERS: [u64; 10] = [
|
||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
|
||||
];
|
||||
const BASE10_STEP: i32 = 10;
|
||||
const BASE10_BIAS: i32 = 350;
|
||||
|
||||
// HIGH LEVEL
|
||||
// ----------
|
||||
|
||||
const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers {
|
||||
small: ExtendedFloatArray {
|
||||
mant: &BASE10_SMALL_MANTISSA,
|
||||
exp: &BASE10_SMALL_EXPONENT,
|
||||
},
|
||||
large: ExtendedFloatArray {
|
||||
mant: &BASE10_LARGE_MANTISSA,
|
||||
exp: &BASE10_LARGE_EXPONENT,
|
||||
},
|
||||
small_int: &BASE10_SMALL_INT_POWERS,
|
||||
step: BASE10_STEP,
|
||||
bias: BASE10_BIAS,
|
||||
};
|
||||
|
||||
/// Get powers from base.
|
||||
pub(crate) fn get_powers() -> &'static ModeratePathPowers {
|
||||
&BASE10_POWERS
|
||||
}
|
18
vendor/serde_json/src/lexical/digit.rs
vendored
Normal file
18
vendor/serde_json/src/lexical/digit.rs
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Helpers to convert and add digits from characters.
|
||||
|
||||
// Convert u8 to digit.
|
||||
#[inline]
|
||||
pub(crate) fn to_digit(c: u8) -> Option<u32> {
|
||||
(c as char).to_digit(10)
|
||||
}
|
||||
|
||||
// Add digit to mantissa.
|
||||
#[inline]
|
||||
pub(crate) fn add_digit(value: u64, digit: u32) -> Option<u64> {
|
||||
match value.checked_mul(10) {
|
||||
None => None,
|
||||
Some(n) => n.checked_add(digit as u64),
|
||||
}
|
||||
}
|
132
vendor/serde_json/src/lexical/errors.rs
vendored
Normal file
132
vendor/serde_json/src/lexical/errors.rs
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Estimate the error in an 80-bit approximation of a float.
|
||||
//!
|
||||
//! This estimates the error in a floating-point representation.
|
||||
//!
|
||||
//! This implementation is loosely based off the Golang implementation,
|
||||
//! found here: <https://golang.org/src/strconv/atof.go>
|
||||
|
||||
use super::float::*;
|
||||
use super::num::*;
|
||||
use super::rounding::*;
|
||||
|
||||
pub(crate) trait FloatErrors {
|
||||
/// Get the full error scale.
|
||||
fn error_scale() -> u32;
|
||||
/// Get the half error scale.
|
||||
fn error_halfscale() -> u32;
|
||||
/// Determine if the number of errors is tolerable for float precision.
|
||||
fn error_is_accurate<F: Float>(count: u32, fp: &ExtendedFloat) -> bool;
|
||||
}
|
||||
|
||||
/// Check if the error is accurate with a round-nearest rounding scheme.
|
||||
#[inline]
|
||||
fn nearest_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool {
|
||||
// Round-to-nearest, need to use the halfway point.
|
||||
if extrabits == 65 {
|
||||
// Underflow, we have a shift larger than the mantissa.
|
||||
// Representation is valid **only** if the value is close enough
|
||||
// overflow to the next bit within errors. If it overflows,
|
||||
// the representation is **not** valid.
|
||||
!fp.mant.overflowing_add(errors).1
|
||||
} else {
|
||||
let mask: u64 = lower_n_mask(extrabits);
|
||||
let extra: u64 = fp.mant & mask;
|
||||
|
||||
// Round-to-nearest, need to check if we're close to halfway.
|
||||
// IE, b10100 | 100000, where `|` signifies the truncation point.
|
||||
let halfway: u64 = lower_n_halfway(extrabits);
|
||||
let cmp1 = halfway.wrapping_sub(errors) < extra;
|
||||
let cmp2 = extra < halfway.wrapping_add(errors);
|
||||
|
||||
// If both comparisons are true, we have significant rounding error,
|
||||
// and the value cannot be exactly represented. Otherwise, the
|
||||
// representation is valid.
|
||||
!(cmp1 && cmp2)
|
||||
}
|
||||
}
|
||||
|
||||
impl FloatErrors for u64 {
|
||||
#[inline]
|
||||
fn error_scale() -> u32 {
|
||||
8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn error_halfscale() -> u32 {
|
||||
u64::error_scale() / 2
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn error_is_accurate<F: Float>(count: u32, fp: &ExtendedFloat) -> bool {
|
||||
// Determine if extended-precision float is a good approximation.
|
||||
// If the error has affected too many units, the float will be
|
||||
// inaccurate, or if the representation is too close to halfway
|
||||
// that any operations could affect this halfway representation.
|
||||
// See the documentation for dtoa for more information.
|
||||
let bias = -(F::EXPONENT_BIAS - F::MANTISSA_SIZE);
|
||||
let denormal_exp = bias - 63;
|
||||
// This is always a valid u32, since (denormal_exp - fp.exp)
|
||||
// will always be positive and the significand size is {23, 52}.
|
||||
let extrabits = if fp.exp <= denormal_exp {
|
||||
64 - F::MANTISSA_SIZE + denormal_exp - fp.exp
|
||||
} else {
|
||||
63 - F::MANTISSA_SIZE
|
||||
};
|
||||
|
||||
// Our logic is as follows: we want to determine if the actual
|
||||
// mantissa and the errors during calculation differ significantly
|
||||
// from the rounding point. The rounding point for round-nearest
|
||||
// is the halfway point, IE, this when the truncated bits start
|
||||
// with b1000..., while the rounding point for the round-toward
|
||||
// is when the truncated bits are equal to 0.
|
||||
// To do so, we can check whether the rounding point +/- the error
|
||||
// are >/< the actual lower n bits.
|
||||
//
|
||||
// For whether we need to use signed or unsigned types for this
|
||||
// analysis, see this example, using u8 rather than u64 to simplify
|
||||
// things.
|
||||
//
|
||||
// # Comparisons
|
||||
// cmp1 = (halfway - errors) < extra
|
||||
// cmp1 = extra < (halfway + errors)
|
||||
//
|
||||
// # Large Extrabits, Low Errors
|
||||
//
|
||||
// extrabits = 8
|
||||
// halfway = 0b10000000
|
||||
// extra = 0b10000010
|
||||
// errors = 0b00000100
|
||||
// halfway - errors = 0b01111100
|
||||
// halfway + errors = 0b10000100
|
||||
//
|
||||
// Unsigned:
|
||||
// halfway - errors = 124
|
||||
// halfway + errors = 132
|
||||
// extra = 130
|
||||
// cmp1 = true
|
||||
// cmp2 = true
|
||||
// Signed:
|
||||
// halfway - errors = 124
|
||||
// halfway + errors = -124
|
||||
// extra = -126
|
||||
// cmp1 = false
|
||||
// cmp2 = true
|
||||
//
|
||||
// # Conclusion
|
||||
//
|
||||
// Since errors will always be small, and since we want to detect
|
||||
// if the representation is accurate, we need to use an **unsigned**
|
||||
// type for comparisons.
|
||||
|
||||
let extrabits = extrabits as u64;
|
||||
let errors = count as u64;
|
||||
if extrabits > 65 {
|
||||
// Underflow, we have a literal 0.
|
||||
return true;
|
||||
}
|
||||
|
||||
nearest_error_is_accurate(errors, fp, extrabits)
|
||||
}
|
||||
}
|
50
vendor/serde_json/src/lexical/exponent.rs
vendored
Normal file
50
vendor/serde_json/src/lexical/exponent.rs
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Utilities to calculate exponents.
|
||||
|
||||
/// Convert usize into i32 without overflow.
|
||||
///
|
||||
/// This is needed to ensure when adjusting the exponent relative to
|
||||
/// the mantissa we do not overflow for comically-long exponents.
|
||||
#[inline]
|
||||
fn into_i32(value: usize) -> i32 {
|
||||
if value > i32::max_value() as usize {
|
||||
i32::max_value()
|
||||
} else {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
// EXPONENT CALCULATION
|
||||
|
||||
// Calculate the scientific notation exponent without overflow.
|
||||
//
|
||||
// For example, 0.1 would be -1, and 10 would be 1 in base 10.
|
||||
#[inline]
|
||||
pub(crate) fn scientific_exponent(
|
||||
exponent: i32,
|
||||
integer_digits: usize,
|
||||
fraction_start: usize,
|
||||
) -> i32 {
|
||||
if integer_digits == 0 {
|
||||
let fraction_start = into_i32(fraction_start);
|
||||
exponent.saturating_sub(fraction_start).saturating_sub(1)
|
||||
} else {
|
||||
let integer_shift = into_i32(integer_digits - 1);
|
||||
exponent.saturating_add(integer_shift)
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the mantissa exponent without overflow.
|
||||
//
|
||||
// Remove the number of digits that contributed to the mantissa past
|
||||
// the dot, and add the number of truncated digits from the mantissa,
|
||||
// to calculate the scaling factor for the mantissa from a raw exponent.
|
||||
#[inline]
|
||||
pub(crate) fn mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i32 {
|
||||
if fraction_digits > truncated {
|
||||
exponent.saturating_sub(into_i32(fraction_digits - truncated))
|
||||
} else {
|
||||
exponent.saturating_add(into_i32(truncated - fraction_digits))
|
||||
}
|
||||
}
|
183
vendor/serde_json/src/lexical/float.rs
vendored
Normal file
183
vendor/serde_json/src/lexical/float.rs
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
// FLOAT TYPE
|
||||
|
||||
use super::num::*;
|
||||
use super::rounding::*;
|
||||
use super::shift::*;
|
||||
|
||||
/// Extended precision floating-point type.
|
||||
///
|
||||
/// Private implementation, exposed only for testing purposes.
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct ExtendedFloat {
|
||||
/// Mantissa for the extended-precision float.
|
||||
pub mant: u64,
|
||||
/// Binary exponent for the extended-precision float.
|
||||
pub exp: i32,
|
||||
}
|
||||
|
||||
impl ExtendedFloat {
|
||||
// PROPERTIES
|
||||
|
||||
// OPERATIONS
|
||||
|
||||
/// Multiply two normalized extended-precision floats, as if by `a*b`.
|
||||
///
|
||||
/// The precision is maximal when the numbers are normalized, however,
|
||||
/// decent precision will occur as long as both values have high bits
|
||||
/// set. The result is not normalized.
|
||||
///
|
||||
/// Algorithm:
|
||||
/// 1. Non-signed multiplication of mantissas (requires 2x as many bits as input).
|
||||
/// 2. Normalization of the result (not done here).
|
||||
/// 3. Addition of exponents.
|
||||
pub(crate) fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat {
|
||||
// Logic check, values must be decently normalized prior to multiplication.
|
||||
debug_assert!((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0));
|
||||
|
||||
// Extract high-and-low masks.
|
||||
let ah = self.mant >> u64::HALF;
|
||||
let al = self.mant & u64::LOMASK;
|
||||
let bh = b.mant >> u64::HALF;
|
||||
let bl = b.mant & u64::LOMASK;
|
||||
|
||||
// Get our products
|
||||
let ah_bl = ah * bl;
|
||||
let al_bh = al * bh;
|
||||
let al_bl = al * bl;
|
||||
let ah_bh = ah * bh;
|
||||
|
||||
let mut tmp = (ah_bl & u64::LOMASK) + (al_bh & u64::LOMASK) + (al_bl >> u64::HALF);
|
||||
// round up
|
||||
tmp += 1 << (u64::HALF - 1);
|
||||
|
||||
ExtendedFloat {
|
||||
mant: ah_bh + (ah_bl >> u64::HALF) + (al_bh >> u64::HALF) + (tmp >> u64::HALF),
|
||||
exp: self.exp + b.exp + u64::FULL,
|
||||
}
|
||||
}
|
||||
|
||||
/// Multiply in-place, as if by `a*b`.
|
||||
///
|
||||
/// The result is not normalized.
|
||||
#[inline]
|
||||
pub(crate) fn imul(&mut self, b: &ExtendedFloat) {
|
||||
*self = self.mul(b);
|
||||
}
|
||||
|
||||
// NORMALIZE
|
||||
|
||||
/// Normalize float-point number.
|
||||
///
|
||||
/// Shift the mantissa so the number of leading zeros is 0, or the value
|
||||
/// itself is 0.
|
||||
///
|
||||
/// Get the number of bytes shifted.
|
||||
#[inline]
|
||||
pub(crate) fn normalize(&mut self) -> u32 {
|
||||
// Note:
|
||||
// Using the cltz intrinsic via leading_zeros is way faster (~10x)
|
||||
// than shifting 1-bit at a time, via while loop, and also way
|
||||
// faster (~2x) than an unrolled loop that checks at 32, 16, 4,
|
||||
// 2, and 1 bit.
|
||||
//
|
||||
// Using a modulus of pow2 (which will get optimized to a bitwise
|
||||
// and with 0x3F or faster) is slightly slower than an if/then,
|
||||
// however, removing the if/then will likely optimize more branched
|
||||
// code as it removes conditional logic.
|
||||
|
||||
// Calculate the number of leading zeros, and then zero-out
|
||||
// any overflowing bits, to avoid shl overflow when self.mant == 0.
|
||||
let shift = if self.mant == 0 {
|
||||
0
|
||||
} else {
|
||||
self.mant.leading_zeros()
|
||||
};
|
||||
shl(self, shift as i32);
|
||||
shift
|
||||
}
|
||||
|
||||
// ROUND
|
||||
|
||||
/// Lossy round float-point number to native mantissa boundaries.
|
||||
#[inline]
|
||||
pub(crate) fn round_to_native<F, Algorithm>(&mut self, algorithm: Algorithm)
|
||||
where
|
||||
F: Float,
|
||||
Algorithm: FnOnce(&mut ExtendedFloat, i32),
|
||||
{
|
||||
round_to_native::<F, _>(self, algorithm);
|
||||
}
|
||||
|
||||
// FROM
|
||||
|
||||
/// Create extended float from native float.
|
||||
#[inline]
|
||||
pub fn from_float<F: Float>(f: F) -> ExtendedFloat {
|
||||
from_float(f)
|
||||
}
|
||||
|
||||
// INTO
|
||||
|
||||
/// Convert into default-rounded, lower-precision native float.
|
||||
#[inline]
|
||||
pub(crate) fn into_float<F: Float>(mut self) -> F {
|
||||
self.round_to_native::<F, _>(round_nearest_tie_even);
|
||||
into_float(self)
|
||||
}
|
||||
|
||||
/// Convert into downward-rounded, lower-precision native float.
|
||||
#[inline]
|
||||
pub(crate) fn into_downward_float<F: Float>(mut self) -> F {
|
||||
self.round_to_native::<F, _>(round_downward);
|
||||
into_float(self)
|
||||
}
|
||||
}
|
||||
|
||||
// FROM FLOAT
|
||||
|
||||
// Import ExtendedFloat from native float.
|
||||
#[inline]
|
||||
pub(crate) fn from_float<F>(f: F) -> ExtendedFloat
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
ExtendedFloat {
|
||||
mant: u64::as_cast(f.mantissa()),
|
||||
exp: f.exponent(),
|
||||
}
|
||||
}
|
||||
|
||||
// INTO FLOAT
|
||||
|
||||
// Export extended-precision float to native float.
|
||||
//
|
||||
// The extended-precision float must be in native float representation,
|
||||
// with overflow/underflow appropriately handled.
|
||||
#[inline]
|
||||
pub(crate) fn into_float<F>(fp: ExtendedFloat) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Export floating-point number.
|
||||
if fp.mant == 0 || fp.exp < F::DENORMAL_EXPONENT {
|
||||
// sub-denormal, underflow
|
||||
F::ZERO
|
||||
} else if fp.exp >= F::MAX_EXPONENT {
|
||||
// overflow
|
||||
F::from_bits(F::INFINITY_BITS)
|
||||
} else {
|
||||
// calculate the exp and fraction bits, and return a float from bits.
|
||||
let exp: u64;
|
||||
if (fp.exp == F::DENORMAL_EXPONENT) && (fp.mant & F::HIDDEN_BIT_MASK.as_u64()) == 0 {
|
||||
exp = 0;
|
||||
} else {
|
||||
exp = (fp.exp + F::EXPONENT_BIAS) as u64;
|
||||
}
|
||||
let exp = exp << F::MANTISSA_SIZE;
|
||||
let mant = fp.mant & F::MANTISSA_MASK.as_u64();
|
||||
F::from_bits(F::Unsigned::as_cast(mant | exp))
|
||||
}
|
||||
}
|
9
vendor/serde_json/src/lexical/large_powers.rs
vendored
Normal file
9
vendor/serde_json/src/lexical/large_powers.rs
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Precalculated large powers for limbs.
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
pub(crate) use super::large_powers32::*;
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
pub(crate) use super::large_powers64::*;
|
183
vendor/serde_json/src/lexical/large_powers32.rs
vendored
Normal file
183
vendor/serde_json/src/lexical/large_powers32.rs
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Precalculated large powers for 32-bit limbs.
|
||||
|
||||
/// Large powers (&[u32]) for base5 operations.
|
||||
const POW5_1: [u32; 1] = [5];
|
||||
const POW5_2: [u32; 1] = [25];
|
||||
const POW5_3: [u32; 1] = [625];
|
||||
const POW5_4: [u32; 1] = [390625];
|
||||
const POW5_5: [u32; 2] = [2264035265, 35];
|
||||
const POW5_6: [u32; 3] = [2242703233, 762134875, 1262];
|
||||
const POW5_7: [u32; 5] = [3211403009, 1849224548, 3668416493, 3913284084, 1593091];
|
||||
const POW5_8: [u32; 10] = [
|
||||
781532673, 64985353, 253049085, 594863151, 3553621484, 3288652808, 3167596762, 2788392729,
|
||||
3911132675, 590,
|
||||
];
|
||||
const POW5_9: [u32; 19] = [
|
||||
2553183233, 3201533787, 3638140786, 303378311, 1809731782, 3477761648, 3583367183, 649228654,
|
||||
2915460784, 487929380, 1011012442, 1677677582, 3428152256, 1710878487, 1438394610, 2161952759,
|
||||
4100910556, 1608314830, 349175,
|
||||
];
|
||||
const POW5_10: [u32; 38] = [
|
||||
4234999809, 2012377703, 2408924892, 1570150255, 3090844311, 3273530073, 1187251475, 2498123591,
|
||||
3364452033, 1148564857, 687371067, 2854068671, 1883165473, 505794538, 2988060450, 3159489326,
|
||||
2531348317, 3215191468, 849106862, 3892080979, 3288073877, 2242451748, 4183778142, 2995818208,
|
||||
2477501924, 325481258, 2487842652, 1774082830, 1933815724, 2962865281, 1168579910, 2724829000,
|
||||
2360374019, 2315984659, 2360052375, 3251779801, 1664357844, 28,
|
||||
];
|
||||
const POW5_11: [u32; 75] = [
|
||||
689565697, 4116392818, 1853628763, 516071302, 2568769159, 365238920, 336250165, 1283268122,
|
||||
3425490969, 248595470, 2305176814, 2111925499, 507770399, 2681111421, 589114268, 591287751,
|
||||
1708941527, 4098957707, 475844916, 3378731398, 2452339615, 2817037361, 2678008327, 1656645978,
|
||||
2383430340, 73103988, 448667107, 2329420453, 3124020241, 3625235717, 3208634035, 2412059158,
|
||||
2981664444, 4117622508, 838560765, 3069470027, 270153238, 1802868219, 3692709886, 2161737865,
|
||||
2159912357, 2585798786, 837488486, 4237238160, 2540319504, 3798629246, 3748148874, 1021550776,
|
||||
2386715342, 1973637538, 1823520457, 1146713475, 833971519, 3277251466, 905620390, 26278816,
|
||||
2680483154, 2294040859, 373297482, 5996609, 4109575006, 512575049, 917036550, 1942311753,
|
||||
2816916778, 3248920332, 1192784020, 3537586671, 2456567643, 2925660628, 759380297, 888447942,
|
||||
3559939476, 3654687237, 805,
|
||||
];
|
||||
const POW5_12: [u32; 149] = [
|
||||
322166785, 3809044581, 2994556223, 1239584207, 3962455841, 4001882964, 3053876612, 915114683,
|
||||
2783289745, 785739093, 4253185907, 3931164994, 1370983858, 2553556126, 3360742076, 2255410929,
|
||||
422849554, 2457422215, 3539495362, 1720790602, 1908931983, 1470596141, 592794347, 4219465164,
|
||||
4085652704, 941661409, 2534650953, 885063988, 2355909854, 2812815516, 767256131, 3821757683,
|
||||
2155151105, 3817418473, 281116564, 2834395026, 2821201622, 2524625843, 1511330880, 2572352493,
|
||||
330571332, 2951088579, 2730271766, 4044456479, 4212286644, 2444937588, 3603420843, 2387148597,
|
||||
1142537539, 3299235429, 1751012624, 861228086, 2873722519, 230498814, 1023297821, 2553128038,
|
||||
3421129895, 2651917435, 2042981258, 1606787143, 2228751918, 447345732, 1930371132, 1784132011,
|
||||
3612538790, 2275925090, 2487567871, 1080427616, 2009179183, 3383506781, 3899054063, 1950782960,
|
||||
2168622213, 2717674390, 3616636027, 2079341593, 1530129217, 1461057425, 2406264415, 3674671357,
|
||||
2972036238, 2019354295, 1455849819, 1866918619, 1324269294, 424891864, 2722422332, 2641594816,
|
||||
1400249021, 3482963993, 3734946379, 225889849, 1891545473, 777383150, 3589824633, 4117601611,
|
||||
4220028667, 334453379, 1083130821, 1060342180, 4208163139, 1489826908, 4163762246, 1096580926,
|
||||
689301528, 2336054516, 1782865703, 4175148410, 3398369392, 2329412588, 3001580596, 59740741,
|
||||
3202189932, 3351895776, 246185302, 718535188, 3772647488, 4151666556, 4055698133, 2461934110,
|
||||
2281316281, 3466396836, 3536023465, 1064267812, 2955456354, 2423805422, 3627960790, 1325057500,
|
||||
3876919979, 2009959531, 175455101, 184092852, 2358785571, 3842977831, 2485266289, 487121622,
|
||||
4159252710, 4075707558, 459389244, 300652075, 2521346588, 3458976673, 888631636, 2076098096,
|
||||
3844514585, 2363697580, 3729421522, 3051115477, 649395,
|
||||
];
|
||||
const POW5_13: [u32; 298] = [
|
||||
711442433, 3564261005, 2399042279, 4170849936, 4010295575, 1423987028, 330414929, 1349249065,
|
||||
4213813618, 3852031822, 4040843590, 2154565331, 3094013374, 1159028371, 3227065538, 2115927092,
|
||||
2085102554, 488590542, 2609619432, 3602898805, 3812736528, 3269439096, 23816114, 253984538,
|
||||
1035905997, 2942969204, 3400787671, 338562688, 1637191975, 740509713, 2264962817, 3410753922,
|
||||
4162231428, 2282041228, 1759373012, 3155367777, 4278913285, 1420532801, 1981002276, 438054990,
|
||||
1006507643, 1142697287, 1332538012, 2029019521, 3949305784, 818392641, 2491288846, 2716584663,
|
||||
3648886102, 556814413, 444795339, 4071412999, 1066321706, 4253169466, 2510832316, 672091442,
|
||||
4083256000, 2165985028, 1841538484, 3549854235, 364431512, 3707648143, 1162785440, 2268641545,
|
||||
281340310, 735693841, 848809228, 1700785200, 2919703985, 4094234344, 58530286, 965505005,
|
||||
1000010347, 3381961808, 3040089923, 1973852082, 2890971585, 1019960210, 4292895237, 2821887841,
|
||||
3756675650, 3951282907, 3885870583, 1008791145, 503998487, 1881258362, 1949332730, 392996726,
|
||||
2012973814, 3970014187, 2461725150, 2942547730, 3728066699, 2766901132, 3778532841, 1085564064,
|
||||
2278673896, 1116879805, 3448726271, 774279411, 157211670, 1506320155, 531168605, 1362654525,
|
||||
956967721, 2148871960, 769186085, 4186232894, 2055679604, 3248365487, 3981268013, 3975787984,
|
||||
2489510517, 3309046495, 212771124, 933418041, 3371839114, 562115198, 1853601831, 757336096,
|
||||
1354633440, 1486083256, 2872126393, 522920738, 1141587749, 3210903262, 1926940553, 3054024853,
|
||||
2021162538, 2262742000, 1877899947, 3147002868, 669840763, 4158174590, 4238502559, 1023731922,
|
||||
3386840011, 829588074, 3449720188, 2835142880, 2999162007, 813056473, 482949569, 638108879,
|
||||
3067201471, 1026714238, 4004452838, 2383667807, 3999477803, 771648919, 630660440, 3827121348,
|
||||
176185980, 2878191002, 2666149832, 3909811063, 2429163983, 2665690412, 907266128, 4269332098,
|
||||
2022665808, 1527122180, 3072053668, 1072477492, 3006022924, 549664855, 2800340954, 37352654,
|
||||
1212772743, 2711280533, 3029527946, 2511120040, 1305308377, 3474662224, 4226330922, 442988428,
|
||||
954940108, 3274548099, 4212288177, 2688499880, 3982226758, 3922609956, 1279948029, 1939943640,
|
||||
3650489901, 2733364929, 2494263275, 1864579964, 1225941120, 2390465139, 1267503249, 3533240729,
|
||||
904410805, 2842550015, 2517736241, 1796069820, 3335274381, 673539835, 1924694759, 3598098235,
|
||||
2792633405, 16535707, 3703535497, 3592841791, 2929082877, 1317622811, 294990855, 1396706563,
|
||||
2383271770, 3853857605, 277813677, 277580220, 1101318484, 3761974115, 1132150143, 2544692622,
|
||||
3419825776, 743770306, 1695464553, 1548693232, 2421159615, 2575672031, 2678971806, 1591267897,
|
||||
626546738, 3823443129, 267710932, 1455435162, 2353985540, 3248523795, 335348168, 3872552561,
|
||||
2814522612, 2634118860, 3503767026, 1301019273, 1414467789, 722985138, 3070909565, 4253482569,
|
||||
3744939841, 558142907, 2229819389, 13833173, 77003966, 2763671364, 3905603970, 2931990126,
|
||||
2280419384, 1879090457, 2934846267, 4284933164, 2331863845, 62191163, 3178861020, 1522063815,
|
||||
785672270, 1215568492, 2936443917, 802972489, 2956820173, 3916732783, 2893572089, 1391232801,
|
||||
3168640330, 2396859648, 894950918, 1103583736, 961991865, 2807302642, 305977505, 3054505899,
|
||||
1048256994, 781017659, 2459278754, 3164823415, 537658277, 905753687, 464963300, 4149131560,
|
||||
1029507924, 2278300961, 1231291503, 414073408, 3630740085, 2345841814, 475358196, 3258243317,
|
||||
4167625072, 4178911231, 2927355042, 655438830, 3138378018, 623200562, 2785714112, 273403236,
|
||||
807993669, 98,
|
||||
];
|
||||
const POW5_14: [u32; 595] = [
|
||||
1691320321, 2671006246, 1682531301, 2072858707, 1240508969, 3108358191, 1125119096, 2470144952,
|
||||
1610099978, 1690632660, 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936,
|
||||
4078768933, 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313,
|
||||
1254424514, 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749,
|
||||
2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861, 125491448,
|
||||
1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701, 483795093,
|
||||
1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571, 1094885097, 4223064276,
|
||||
3307819021, 651121777, 1757003305, 3603542336, 129917786, 2215974994, 3042386306, 2205352757,
|
||||
3944939700, 3710987569, 97967515, 1217242524, 930630949, 3660328512, 1787663098, 1784141600,
|
||||
2500542892, 4034561586, 3444961378, 785043562, 3869499367, 885623728, 2625011087, 3053789617,
|
||||
1965731793, 3900511934, 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160,
|
||||
1348009103, 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552,
|
||||
2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748, 1739996642,
|
||||
1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406, 785287846, 1671499798,
|
||||
433044045, 1919608025, 264833858, 3999983367, 1116778570, 1301982149, 4213901070, 4081649357,
|
||||
536169226, 1389008649, 188923873, 373495152, 2551132278, 1800758715, 3951840330, 2632334454,
|
||||
3118778225, 1034046547, 1862428410, 3037609062, 1994608505, 29051798, 2571685694, 264151332,
|
||||
2260643090, 2717535964, 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570,
|
||||
3676533911, 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173,
|
||||
1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527, 2507669891,
|
||||
2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954, 2204775591, 1037094060,
|
||||
829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123, 488286513, 50685385,
|
||||
3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248, 3708476086, 10375249,
|
||||
4172112346, 2117510871, 2227658327, 3187664554, 3050656558, 328034318, 3179601324, 1247769761,
|
||||
3439263953, 1431538938, 2962525068, 1213366289, 3813013550, 2651093719, 1860661503, 3933716208,
|
||||
264320617, 789980519, 2257856172, 102000748, 977269860, 1113845122, 3008928583, 1461738106,
|
||||
557786285, 2926560363, 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056,
|
||||
2076808229, 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232,
|
||||
2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742,
|
||||
3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881, 3227511198,
|
||||
2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386, 584244184, 1450926016,
|
||||
2462430443, 3226534010, 298582169, 4214576928, 1762099469, 964985185, 1585788148, 1641127666,
|
||||
787006566, 2315956284, 3258232694, 2275058964, 2541003317, 1508235863, 2613339827, 4080647514,
|
||||
1152057965, 3149266279, 731345410, 914737650, 65395712, 1884566942, 1379520432, 2611027720,
|
||||
4163073378, 2619704967, 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279,
|
||||
4051522914, 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776,
|
||||
253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225,
|
||||
2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199, 292769859,
|
||||
2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636, 3540280538, 2982120874,
|
||||
2136414455, 255762046, 3852783591, 3262064164, 2358991588, 3756586117, 4143612643, 3326743817,
|
||||
2897365738, 807711264, 3719310016, 3721264861, 3627337076, 944539331, 3640975513, 3712525681,
|
||||
1162911839, 2008243316, 2179489649, 2867584109, 261861553, 3570253908, 2062868357, 2220328623,
|
||||
3857004679, 3744109002, 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584,
|
||||
1223182946, 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643,
|
||||
400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761,
|
||||
3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362, 3454286017,
|
||||
2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345, 1381875722, 1661526119,
|
||||
1082778324, 3571910052, 1140625929, 851544870, 1145546234, 2938573139, 907528924, 1304752338,
|
||||
1764668294, 1788942063, 1700368828, 104979467, 1413911959, 3327497828, 1956384744, 1272712474,
|
||||
2815637534, 3307809377, 1320574940, 1111968962, 4073107827, 434096622, 169451929, 3201183459,
|
||||
3331028877, 2852366972, 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722,
|
||||
2721281595, 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708,
|
||||
992340967, 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683,
|
||||
1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270, 173719711,
|
||||
3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998, 3573073830,
|
||||
841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278, 3964109906, 677238797,
|
||||
537994297, 1124184993, 4287078344, 4207654540, 2943022776, 2977947524, 3255359985, 4098397558,
|
||||
2274666217, 2915862060, 243524940, 2467726756, 2869020032, 507521339, 3403121914, 522051455,
|
||||
1803903108, 3471254194, 473535371, 1948602036, 3352095732, 3116527002, 1795743673, 775867940,
|
||||
2551469548, 3757442064, 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130,
|
||||
1342349989, 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609,
|
||||
1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726, 2821790499,
|
||||
2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345, 378322447, 156541411,
|
||||
1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024, 4166396241, 509467541,
|
||||
2906024136, 1221753746, 3375413222, 431327897, 2749265123, 2848827671, 3412997614, 2051920238,
|
||||
1283516885, 1300498239, 1957256104, 2634010560, 3531900395, 360276850, 1461184973, 2012063967,
|
||||
2873572430, 2914608609, 4289554777, 1539331673, 1859532928, 4213441063, 538215691, 3512720863,
|
||||
4258743698, 3040408445, 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460,
|
||||
2864275059, 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456,
|
||||
2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775, 3887426070,
|
||||
3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114, 1596072055, 1928415752,
|
||||
3635452689, 1005598891, 3335462724, 3290848636, 3669078247, 1178176812, 2110774376, 3068593619,
|
||||
1253036518, 908857731, 3631223047, 4138506423, 2903592318, 3596915748, 3289036113, 3721512676,
|
||||
2704409359, 3386016968, 3676268074, 2185259502, 1096257611, 3360076717, 3548676554, 170167319,
|
||||
3360064287, 3899940843, 9640,
|
||||
];
|
||||
|
||||
pub(crate) const POW5: [&'static [u32]; 14] = [
|
||||
&POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10,
|
||||
&POW5_11, &POW5_12, &POW5_13, &POW5_14,
|
||||
];
|
625
vendor/serde_json/src/lexical/large_powers64.rs
vendored
Normal file
625
vendor/serde_json/src/lexical/large_powers64.rs
vendored
Normal file
@ -0,0 +1,625 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Precalculated large powers for 64-bit limbs.
|
||||
|
||||
/// Large powers (&[u64]) for base5 operations.
|
||||
const POW5_1: [u64; 1] = [5];
|
||||
const POW5_2: [u64; 1] = [25];
|
||||
const POW5_3: [u64; 1] = [625];
|
||||
const POW5_4: [u64; 1] = [390625];
|
||||
const POW5_5: [u64; 1] = [152587890625];
|
||||
const POW5_6: [u64; 2] = [3273344365508751233, 1262];
|
||||
const POW5_7: [u64; 3] = [7942358959831785217, 16807427164405733357, 1593091];
|
||||
const POW5_8: [u64; 5] = [
|
||||
279109966635548161,
|
||||
2554917779393558781,
|
||||
14124656261812188652,
|
||||
11976055582626787546,
|
||||
2537941837315,
|
||||
];
|
||||
const POW5_9: [u64; 10] = [
|
||||
13750482914757213185,
|
||||
1302999927698857842,
|
||||
14936872543252795590,
|
||||
2788415840139466767,
|
||||
2095640732773017264,
|
||||
7205570348933370714,
|
||||
7348167152523113408,
|
||||
9285516396840364274,
|
||||
6907659600622710236,
|
||||
349175,
|
||||
];
|
||||
const POW5_10: [u64; 19] = [
|
||||
8643096425819600897,
|
||||
6743743997439985372,
|
||||
14059704609098336919,
|
||||
10729359125898331411,
|
||||
4933048501514368705,
|
||||
12258131603170554683,
|
||||
2172371001088594721,
|
||||
13569903330219142946,
|
||||
13809142207969578845,
|
||||
16716360519037769646,
|
||||
9631256923806107285,
|
||||
12866941232305103710,
|
||||
1397931361048440292,
|
||||
7619627737732970332,
|
||||
12725409486282665900,
|
||||
11703051443360963910,
|
||||
9947078370803086083,
|
||||
13966287901448440471,
|
||||
121923442132,
|
||||
];
|
||||
const POW5_11: [u64; 38] = [
|
||||
17679772531488845825,
|
||||
2216509366347768155,
|
||||
1568689219195129479,
|
||||
5511594616325588277,
|
||||
1067709417009240089,
|
||||
9070650952098657518,
|
||||
11515285870634858015,
|
||||
2539561553659505564,
|
||||
17604889300961091799,
|
||||
14511540856854204724,
|
||||
12099083339557485471,
|
||||
7115240299237943815,
|
||||
313979240050606788,
|
||||
10004784664717172195,
|
||||
15570268847930131473,
|
||||
10359715202835930803,
|
||||
17685054012115162812,
|
||||
13183273382855797757,
|
||||
7743260039872919062,
|
||||
9284593436392572926,
|
||||
11105921222066415013,
|
||||
18198799323400703846,
|
||||
16314988383739458320,
|
||||
4387527177871570570,
|
||||
8476708682254672590,
|
||||
4925096874831034057,
|
||||
14075687868072027455,
|
||||
112866656203221926,
|
||||
9852830467773230418,
|
||||
25755239915196746,
|
||||
2201493076310172510,
|
||||
8342165458688466438,
|
||||
13954006576066379050,
|
||||
15193819059903295636,
|
||||
12565616718911389531,
|
||||
3815854855847885129,
|
||||
15696762163583540628,
|
||||
805,
|
||||
];
|
||||
const POW5_12: [u64; 75] = [
|
||||
16359721904723189761,
|
||||
5323973632697650495,
|
||||
17187956456762001185,
|
||||
3930387638628283780,
|
||||
3374723710406992273,
|
||||
16884225088663222131,
|
||||
10967440051041439154,
|
||||
9686916182456720060,
|
||||
10554548046311730194,
|
||||
7390739362393647554,
|
||||
6316162333127736719,
|
||||
18122464886584070891,
|
||||
4044404959645932768,
|
||||
3801320885861987401,
|
||||
12080950653257274590,
|
||||
16414324262488991299,
|
||||
16395687498836410113,
|
||||
12173633940896186260,
|
||||
10843185433142632150,
|
||||
11048169832730399808,
|
||||
12674828934734683716,
|
||||
17370808310130582550,
|
||||
10500926985433408692,
|
||||
10252725158410704555,
|
||||
14170108270502067523,
|
||||
3698946465517688080,
|
||||
989984870770509463,
|
||||
10965601426733943069,
|
||||
11389898658438335655,
|
||||
6901098232861256586,
|
||||
1921335291173932590,
|
||||
7662788640922083388,
|
||||
9775023833308395430,
|
||||
4640401278902814207,
|
||||
14532050972198413359,
|
||||
8378549018693130223,
|
||||
11672322628395371653,
|
||||
8930704142764178555,
|
||||
6275193859483102017,
|
||||
15782593304269205087,
|
||||
8673060659034172558,
|
||||
8018354414354334043,
|
||||
1824896661540749038,
|
||||
11345563346725559868,
|
||||
14959216444480821949,
|
||||
970189517688324683,
|
||||
3338835207603007873,
|
||||
17684964260791738489,
|
||||
1436466329061721851,
|
||||
4554134986752476101,
|
||||
6398757850768963907,
|
||||
4709779218751158342,
|
||||
10033277748582410264,
|
||||
17932125878679265063,
|
||||
10004750887749091440,
|
||||
256584531835386932,
|
||||
14396282740722731628,
|
||||
3086085133731396950,
|
||||
17831272085689600064,
|
||||
10573926491412564693,
|
||||
14888061047859191737,
|
||||
4570995450261499817,
|
||||
10410165022312935266,
|
||||
5691078631447480790,
|
||||
8632710455805418155,
|
||||
790672778942823293,
|
||||
16505464105756800547,
|
||||
2092171438149740401,
|
||||
17505030673829275878,
|
||||
1291290830058928444,
|
||||
14856191690683232796,
|
||||
8916773426496500052,
|
||||
10152003807578858265,
|
||||
13104441193763861714,
|
||||
649395,
|
||||
];
|
||||
const POW5_13: [u64; 149] = [
|
||||
15308384451594534913,
|
||||
17913664074042735335,
|
||||
6115977719198531863,
|
||||
5794980608663993169,
|
||||
16544350702855106930,
|
||||
9253787637781258566,
|
||||
4977988951675168190,
|
||||
9087837664087448770,
|
||||
2098480401110016986,
|
||||
15474332540882100712,
|
||||
14042133997396540944,
|
||||
1090855284423485362,
|
||||
12639956485351058381,
|
||||
1454115676006639319,
|
||||
3180465001342538023,
|
||||
14649076551958697729,
|
||||
9801292446545910916,
|
||||
13552201410826594004,
|
||||
6101141927469189381,
|
||||
1881431857880609316,
|
||||
4907847477899433595,
|
||||
8714572486973123228,
|
||||
3514969632331374520,
|
||||
11667642286891470094,
|
||||
2391499697425323350,
|
||||
17486585679659076043,
|
||||
18267223761882105642,
|
||||
2886610765822313148,
|
||||
9302834862968900288,
|
||||
15246507846733637044,
|
||||
15924227519624562840,
|
||||
9743741243284697760,
|
||||
3159780987244964246,
|
||||
7304816812369628428,
|
||||
17584602612559717809,
|
||||
4146812420657846766,
|
||||
14525415362681041515,
|
||||
8477630142371600195,
|
||||
4380695748062263745,
|
||||
12119915994367943173,
|
||||
16970630866565485122,
|
||||
4332724980155264503,
|
||||
8079943140620527639,
|
||||
1687908087554405626,
|
||||
17051081099834002166,
|
||||
12638146269730763230,
|
||||
11883749876933445771,
|
||||
4662462156371383785,
|
||||
4796962238316531176,
|
||||
3325504751659868927,
|
||||
6469595803187862550,
|
||||
5852556621152583005,
|
||||
9229334792448387881,
|
||||
17979733373938620709,
|
||||
13951623534175792756,
|
||||
17075879371091039277,
|
||||
14212246479457938037,
|
||||
4008999959804158260,
|
||||
2414266395366403722,
|
||||
3252733766253918247,
|
||||
6382678985007829216,
|
||||
2245927470982310841,
|
||||
13790724502051307301,
|
||||
13116936866733148041,
|
||||
9718402891306794538,
|
||||
13516274400356104875,
|
||||
17859223875778049403,
|
||||
4396895129099725471,
|
||||
3563053650368467915,
|
||||
12176845952536972668,
|
||||
3492050964335269015,
|
||||
2740656767075170753,
|
||||
4409704077614761919,
|
||||
10237775279597492710,
|
||||
3314206875098230827,
|
||||
16437361028114095448,
|
||||
12361736225407656572,
|
||||
16792510651790145480,
|
||||
11449053143229929935,
|
||||
18336641737580333136,
|
||||
6558939822118891088,
|
||||
4606255756908155300,
|
||||
2360792578991605004,
|
||||
160428430149144538,
|
||||
11644861220729221511,
|
||||
10785178451159739786,
|
||||
14923560618031934681,
|
||||
1902620814992781610,
|
||||
14064076995338910412,
|
||||
11547019064112212657,
|
||||
16847481479966225734,
|
||||
8331994491163145469,
|
||||
11739712981738851885,
|
||||
8008309968651120619,
|
||||
10266969595459035264,
|
||||
15175153381217702033,
|
||||
12208659352573720245,
|
||||
7714061140750342961,
|
||||
2892831567213510541,
|
||||
15453714249045017319,
|
||||
71020323573871677,
|
||||
15431137995750602633,
|
||||
5659146884637671933,
|
||||
5998809010488554503,
|
||||
16552192379299157850,
|
||||
1192197967194298797,
|
||||
16157555793424861524,
|
||||
10929371590994640255,
|
||||
3194469143425738352,
|
||||
6651586784672005225,
|
||||
11062427140788057791,
|
||||
6834443579468668318,
|
||||
16421563197797455922,
|
||||
6251046422506172884,
|
||||
13952303462156793860,
|
||||
16632486601871393224,
|
||||
11313454360291325172,
|
||||
5587835232504462834,
|
||||
3105197524618514637,
|
||||
18268568531031972989,
|
||||
2397205535804309313,
|
||||
59413027864729597,
|
||||
11869878125348715710,
|
||||
12592801707270523266,
|
||||
8070632061321113656,
|
||||
18403647807860650811,
|
||||
267109013517069093,
|
||||
6537214311028855260,
|
||||
5220826919973709902,
|
||||
3448740582779163661,
|
||||
16822239213112884941,
|
||||
5975299384311048185,
|
||||
10294433804430712138,
|
||||
4739856055412448774,
|
||||
12057273038326387897,
|
||||
13119002941950056609,
|
||||
3354445304051737058,
|
||||
13592813067499314594,
|
||||
3890182464434078629,
|
||||
17820384357466425060,
|
||||
9785228118969879380,
|
||||
1778431746734556271,
|
||||
10075313876350055029,
|
||||
13994048489400919028,
|
||||
17948287074199726448,
|
||||
2815088342305858722,
|
||||
2676626035777198370,
|
||||
1174257960026283968,
|
||||
421714788677,
|
||||
];
|
||||
const POW5_14: [u64; 298] = [
|
||||
11471884475673051137,
|
||||
8902860357476377573,
|
||||
13350296775839230505,
|
||||
10609191786344608888,
|
||||
7261211985859587338,
|
||||
11439672689354862964,
|
||||
16789708072300570627,
|
||||
4607056528866348430,
|
||||
3202978990421512997,
|
||||
2024899620433984146,
|
||||
17666950207239811774,
|
||||
4233228489390288200,
|
||||
9137580478688460738,
|
||||
4060411066587388546,
|
||||
11119949806060600124,
|
||||
867715462473090103,
|
||||
14382394941384869610,
|
||||
4856042377419278489,
|
||||
8265605599571137921,
|
||||
538981667666252469,
|
||||
4270263388700786523,
|
||||
3281140600308898503,
|
||||
4121392524544394174,
|
||||
2077884106245940229,
|
||||
9773041957329767574,
|
||||
7550623316597646685,
|
||||
8611033926449791714,
|
||||
18137922955420802793,
|
||||
2796546741236224013,
|
||||
15477096484628446761,
|
||||
9517540128113714010,
|
||||
9471917970500821378,
|
||||
15938570248662483124,
|
||||
5228016831978462619,
|
||||
15720991252586974501,
|
||||
7662829825220776698,
|
||||
17328310068068434348,
|
||||
3371736428170309730,
|
||||
3803724952191098855,
|
||||
13115926536504376719,
|
||||
16752571196153442257,
|
||||
16540185467776259880,
|
||||
3432518182450051120,
|
||||
5880364967211798870,
|
||||
12355748840305392783,
|
||||
14196090758536469575,
|
||||
7370123524686686319,
|
||||
6819740424617592686,
|
||||
13037938013537368753,
|
||||
15029273671291927100,
|
||||
3671312928327205696,
|
||||
7473228676544792780,
|
||||
17234079691312938123,
|
||||
14164740848093544419,
|
||||
13169904779481875902,
|
||||
7179036968465894054,
|
||||
8244653688947194445,
|
||||
17179797746073799490,
|
||||
5591970751047577674,
|
||||
17530550506268329742,
|
||||
5965746721852312330,
|
||||
1604149463243472865,
|
||||
7734199791463116918,
|
||||
11305790396015856714,
|
||||
4441196105025505137,
|
||||
13046431581185664762,
|
||||
124776524294606713,
|
||||
1134521334706523966,
|
||||
11671728093344476434,
|
||||
14103440020972933148,
|
||||
3966727403013869059,
|
||||
9828094508409132821,
|
||||
4355682486381147287,
|
||||
10261407143988481234,
|
||||
3800455155249557199,
|
||||
12700901937937547500,
|
||||
18184475466894579360,
|
||||
13267691151779895412,
|
||||
4714157123477697445,
|
||||
10770360171308585263,
|
||||
9083344917597998040,
|
||||
12078649873810212155,
|
||||
18218989082046199377,
|
||||
4454285072780637351,
|
||||
5287307245618354742,
|
||||
16042289702059031730,
|
||||
4131926574212754010,
|
||||
217692071448455473,
|
||||
3624845916216282093,
|
||||
2901203491797614218,
|
||||
6679177724033967080,
|
||||
44561358851332790,
|
||||
9094639944041587162,
|
||||
13690915012276084311,
|
||||
1408896670826320686,
|
||||
5359130319612337580,
|
||||
6148412925099835601,
|
||||
5211368532286409612,
|
||||
11386360825549027374,
|
||||
16895182466965795071,
|
||||
3392940493846427241,
|
||||
438089879085393580,
|
||||
4783928372776399972,
|
||||
6278117363595909959,
|
||||
12569481049412674733,
|
||||
15648622492570893902,
|
||||
1966316336235305115,
|
||||
1603775390515993547,
|
||||
13576113010204316709,
|
||||
10821754650102840474,
|
||||
18198222517222903152,
|
||||
6966163076615302988,
|
||||
1373932372410129684,
|
||||
3285839581819684990,
|
||||
30177575069719475,
|
||||
16447047871247307061,
|
||||
11618654126674833808,
|
||||
990072222556306872,
|
||||
1260682336135768017,
|
||||
13862055046689532489,
|
||||
15668483092844698432,
|
||||
1879572630092764264,
|
||||
13912027797058626108,
|
||||
6231679788219816920,
|
||||
13857858054844167403,
|
||||
18101470072534728857,
|
||||
4144579812461609229,
|
||||
7048589655616599284,
|
||||
9946956499532694630,
|
||||
9771303850109874038,
|
||||
6477823708780339765,
|
||||
17526247621747041971,
|
||||
13525995675852669549,
|
||||
3928768291901239810,
|
||||
8094153383078124544,
|
||||
11214278667728965552,
|
||||
11251547162596832610,
|
||||
5964946855123292381,
|
||||
3622548288590237903,
|
||||
13469765967150053587,
|
||||
17798986288523466082,
|
||||
14684592818807932259,
|
||||
16724077276802963921,
|
||||
7119877993753121290,
|
||||
1864571304902781632,
|
||||
12871984921385213812,
|
||||
9065447042604670298,
|
||||
3987130777300360550,
|
||||
6890545752116901685,
|
||||
17275341711601865750,
|
||||
6296474927799264658,
|
||||
1257436973037243463,
|
||||
13854281781965301421,
|
||||
1657132483318662716,
|
||||
17309399540017292849,
|
||||
12808111630089217242,
|
||||
1098489625264462071,
|
||||
14010458905686364135,
|
||||
16134414519481621220,
|
||||
14288255900328821475,
|
||||
3469093466388187882,
|
||||
15982710881468295872,
|
||||
4056765540058056052,
|
||||
15945176389096104089,
|
||||
8625339365793505375,
|
||||
12316179968863788913,
|
||||
15334123773538054321,
|
||||
9536238824220581765,
|
||||
16080825720106203271,
|
||||
6235695225418121745,
|
||||
12035192956458019349,
|
||||
3235835166714703698,
|
||||
5348960676912581218,
|
||||
15315062772709464647,
|
||||
17335089708021308662,
|
||||
16855855317958414409,
|
||||
2369751139431140406,
|
||||
3693542588628609043,
|
||||
7350405893393987577,
|
||||
17402072586341663801,
|
||||
7007897690013647122,
|
||||
15671767872059304758,
|
||||
9259490518292347915,
|
||||
14836045474406130394,
|
||||
4654005815464502513,
|
||||
6487825998330548401,
|
||||
7013356660323385022,
|
||||
7136200343936679946,
|
||||
15341236858676437716,
|
||||
3657357368867197449,
|
||||
12621075530054608378,
|
||||
5603868621997066972,
|
||||
7683447656788439942,
|
||||
450883379216880060,
|
||||
14291494350184945047,
|
||||
5466258454997635048,
|
||||
14206933098432772126,
|
||||
4775870327277641692,
|
||||
1864430798867181939,
|
||||
13748978265070608793,
|
||||
12250822864261576589,
|
||||
12561896977498605296,
|
||||
16060949594257359328,
|
||||
17775189113543311529,
|
||||
11835965177892927035,
|
||||
4218664174878121437,
|
||||
3499000902478111683,
|
||||
15169853304359126294,
|
||||
7076121963053575143,
|
||||
832652347668916805,
|
||||
1292148207755194737,
|
||||
7556838978364207852,
|
||||
5904021986723518500,
|
||||
4610244652288570024,
|
||||
4526508363195533871,
|
||||
746120481022614726,
|
||||
737965197247830486,
|
||||
4006266184415762653,
|
||||
9272188239892688050,
|
||||
15346235246415709678,
|
||||
11850675997347533184,
|
||||
11181059668610842701,
|
||||
6687857983250662774,
|
||||
2908718488661492818,
|
||||
4828337780126983225,
|
||||
18071738646453002184,
|
||||
12790187227727197880,
|
||||
17602483480871623153,
|
||||
12523532189621855977,
|
||||
10598805712727696716,
|
||||
2179787555896149376,
|
||||
2242193929457337594,
|
||||
14908923241136742532,
|
||||
8369182018012550027,
|
||||
13385381554043022324,
|
||||
3332327430110633913,
|
||||
16138090784046208492,
|
||||
16172324607469047339,
|
||||
8279089815915615244,
|
||||
12872906602736235247,
|
||||
10894545290539475621,
|
||||
15428756545851905023,
|
||||
4155747980686992922,
|
||||
4074479178894544043,
|
||||
66083965608603584,
|
||||
13873786284662268377,
|
||||
8861183628277687555,
|
||||
12119497911296021430,
|
||||
2154012318305274287,
|
||||
15490706314503067312,
|
||||
13643145488710608367,
|
||||
672340241093017103,
|
||||
6039493278284091973,
|
||||
9679797700977436461,
|
||||
18070795828318171174,
|
||||
2188146431134935377,
|
||||
5247392385741514952,
|
||||
1852539214842869734,
|
||||
12235621681634112739,
|
||||
8812930319623534062,
|
||||
5585597406294108629,
|
||||
11312989214475901864,
|
||||
1547377291787797995,
|
||||
8641748937186208205,
|
||||
12518148659168623694,
|
||||
6611379197521520985,
|
||||
18096591571068008576,
|
||||
15087021227100112139,
|
||||
13058454842015958418,
|
||||
1473584652966833794,
|
||||
4387660670140018168,
|
||||
8452836916843525402,
|
||||
14376083294443363955,
|
||||
13998026203969090659,
|
||||
611968444648172645,
|
||||
990232438801273845,
|
||||
18001186324715561929,
|
||||
13470591857250177501,
|
||||
14881554140239420091,
|
||||
16696367836720124495,
|
||||
6328076032778459673,
|
||||
17027497695968504616,
|
||||
10192245646262428833,
|
||||
8282482589527318647,
|
||||
4319014353374321425,
|
||||
14134087271041670980,
|
||||
5060230880114618599,
|
||||
13179509240430058600,
|
||||
3903514232614801894,
|
||||
17774749744702165255,
|
||||
15448635507030969726,
|
||||
15983775238358480209,
|
||||
14542832143965487887,
|
||||
9385618098039514666,
|
||||
14431419612662304843,
|
||||
730863073501675978,
|
||||
16750118380379734815,
|
||||
9640,
|
||||
];
|
||||
|
||||
pub(crate) const POW5: [&[u64]; 14] = [
|
||||
&POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10,
|
||||
&POW5_11, &POW5_12, &POW5_13, &POW5_14,
|
||||
];
|
886
vendor/serde_json/src/lexical/math.rs
vendored
Normal file
886
vendor/serde_json/src/lexical/math.rs
vendored
Normal file
@ -0,0 +1,886 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Building-blocks for arbitrary-precision math.
|
||||
//!
|
||||
//! These algorithms assume little-endian order for the large integer
|
||||
//! buffers, so for a `vec![0, 1, 2, 3]`, `3` is the most significant limb,
|
||||
//! and `0` is the least significant limb.
|
||||
|
||||
use super::large_powers;
|
||||
use super::num::*;
|
||||
use super::small_powers::*;
|
||||
use alloc::vec::Vec;
|
||||
use core::{cmp, iter, mem};
|
||||
|
||||
// ALIASES
|
||||
// -------
|
||||
|
||||
// Type for a single limb of the big integer.
|
||||
//
|
||||
// A limb is analogous to a digit in base10, except, it stores 32-bit
|
||||
// or 64-bit numbers instead.
|
||||
//
|
||||
// This should be all-known 64-bit platforms supported by Rust.
|
||||
// https://forge.rust-lang.org/platform-support.html
|
||||
//
|
||||
// Platforms where native 128-bit multiplication is explicitly supported:
|
||||
// - x86_64 (Supported via `MUL`).
|
||||
// - mips64 (Supported via `DMULTU`, which `HI` and `LO` can be read-from).
|
||||
//
|
||||
// Platforms where native 64-bit multiplication is supported and
|
||||
// you can extract hi-lo for 64-bit multiplications.
|
||||
// aarch64 (Requires `UMULH` and `MUL` to capture high and low bits).
|
||||
// powerpc64 (Requires `MULHDU` and `MULLD` to capture high and low bits).
|
||||
//
|
||||
// Platforms where native 128-bit multiplication is not supported,
|
||||
// requiring software emulation.
|
||||
// sparc64 (`UMUL` only supported double-word arguments).
|
||||
|
||||
// 32-BIT LIMB
|
||||
#[cfg(limb_width_32)]
|
||||
pub type Limb = u32;
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
pub const POW5_LIMB: &[Limb] = &POW5_32;
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
pub const POW10_LIMB: &[Limb] = &POW10_32;
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
type Wide = u64;
|
||||
|
||||
// 64-BIT LIMB
|
||||
#[cfg(limb_width_64)]
|
||||
pub type Limb = u64;
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
pub const POW5_LIMB: &[Limb] = &POW5_64;
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
pub const POW10_LIMB: &[Limb] = &POW10_64;
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
type Wide = u128;
|
||||
|
||||
/// Cast to limb type.
|
||||
#[inline]
|
||||
pub(crate) fn as_limb<T: Integer>(t: T) -> Limb {
|
||||
Limb::as_cast(t)
|
||||
}
|
||||
|
||||
/// Cast to wide type.
|
||||
#[inline]
|
||||
fn as_wide<T: Integer>(t: T) -> Wide {
|
||||
Wide::as_cast(t)
|
||||
}
|
||||
|
||||
// SPLIT
|
||||
// -----
|
||||
|
||||
/// Split u64 into limbs, in little-endian order.
|
||||
#[inline]
|
||||
#[cfg(limb_width_32)]
|
||||
fn split_u64(x: u64) -> [Limb; 2] {
|
||||
[as_limb(x), as_limb(x >> 32)]
|
||||
}
|
||||
|
||||
/// Split u64 into limbs, in little-endian order.
|
||||
#[inline]
|
||||
#[cfg(limb_width_64)]
|
||||
fn split_u64(x: u64) -> [Limb; 1] {
|
||||
[as_limb(x)]
|
||||
}
|
||||
|
||||
// HI64
|
||||
// ----
|
||||
|
||||
// NONZERO
|
||||
|
||||
/// Check if any of the remaining bits are non-zero.
|
||||
#[inline]
|
||||
pub fn nonzero<T: Integer>(x: &[T], rindex: usize) -> bool {
|
||||
let len = x.len();
|
||||
let slc = &x[..len - rindex];
|
||||
slc.iter().rev().any(|&x| x != T::ZERO)
|
||||
}
|
||||
|
||||
/// Shift 64-bit integer to high 64-bits.
|
||||
#[inline]
|
||||
fn u64_to_hi64_1(r0: u64) -> (u64, bool) {
|
||||
debug_assert!(r0 != 0);
|
||||
let ls = r0.leading_zeros();
|
||||
(r0 << ls, false)
|
||||
}
|
||||
|
||||
/// Shift 2 64-bit integers to high 64-bits.
|
||||
#[inline]
|
||||
fn u64_to_hi64_2(r0: u64, r1: u64) -> (u64, bool) {
|
||||
debug_assert!(r0 != 0);
|
||||
let ls = r0.leading_zeros();
|
||||
let rs = 64 - ls;
|
||||
let v = match ls {
|
||||
0 => r0,
|
||||
_ => (r0 << ls) | (r1 >> rs),
|
||||
};
|
||||
let n = r1 << ls != 0;
|
||||
(v, n)
|
||||
}
|
||||
|
||||
/// Trait to export the high 64-bits from a little-endian slice.
|
||||
trait Hi64<T>: AsRef<[T]> {
|
||||
/// Get the hi64 bits from a 1-limb slice.
|
||||
fn hi64_1(&self) -> (u64, bool);
|
||||
|
||||
/// Get the hi64 bits from a 2-limb slice.
|
||||
fn hi64_2(&self) -> (u64, bool);
|
||||
|
||||
/// Get the hi64 bits from a 3-limb slice.
|
||||
fn hi64_3(&self) -> (u64, bool);
|
||||
|
||||
/// High-level exporter to extract the high 64 bits from a little-endian slice.
|
||||
#[inline]
|
||||
fn hi64(&self) -> (u64, bool) {
|
||||
match self.as_ref().len() {
|
||||
0 => (0, false),
|
||||
1 => self.hi64_1(),
|
||||
2 => self.hi64_2(),
|
||||
_ => self.hi64_3(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Hi64<u32> for [u32] {
|
||||
#[inline]
|
||||
fn hi64_1(&self) -> (u64, bool) {
|
||||
debug_assert!(self.len() == 1);
|
||||
let r0 = self[0] as u64;
|
||||
u64_to_hi64_1(r0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hi64_2(&self) -> (u64, bool) {
|
||||
debug_assert!(self.len() == 2);
|
||||
let r0 = (self[1] as u64) << 32;
|
||||
let r1 = self[0] as u64;
|
||||
u64_to_hi64_1(r0 | r1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hi64_3(&self) -> (u64, bool) {
|
||||
debug_assert!(self.len() >= 3);
|
||||
let r0 = self[self.len() - 1] as u64;
|
||||
let r1 = (self[self.len() - 2] as u64) << 32;
|
||||
let r2 = self[self.len() - 3] as u64;
|
||||
let (v, n) = u64_to_hi64_2(r0, r1 | r2);
|
||||
(v, n || nonzero(self, 3))
|
||||
}
|
||||
}
|
||||
|
||||
impl Hi64<u64> for [u64] {
|
||||
#[inline]
|
||||
fn hi64_1(&self) -> (u64, bool) {
|
||||
debug_assert!(self.len() == 1);
|
||||
let r0 = self[0];
|
||||
u64_to_hi64_1(r0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hi64_2(&self) -> (u64, bool) {
|
||||
debug_assert!(self.len() >= 2);
|
||||
let r0 = self[self.len() - 1];
|
||||
let r1 = self[self.len() - 2];
|
||||
let (v, n) = u64_to_hi64_2(r0, r1);
|
||||
(v, n || nonzero(self, 2))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn hi64_3(&self) -> (u64, bool) {
|
||||
self.hi64_2()
|
||||
}
|
||||
}
|
||||
|
||||
// SCALAR
|
||||
// ------
|
||||
|
||||
// Scalar-to-scalar operations, for building-blocks for arbitrary-precision
|
||||
// operations.
|
||||
|
||||
mod scalar {
|
||||
use super::*;
|
||||
|
||||
// ADDITION
|
||||
|
||||
/// Add two small integers and return the resulting value and if overflow happens.
|
||||
#[inline]
|
||||
pub fn add(x: Limb, y: Limb) -> (Limb, bool) {
|
||||
x.overflowing_add(y)
|
||||
}
|
||||
|
||||
/// AddAssign two small integers and return if overflow happens.
|
||||
#[inline]
|
||||
pub fn iadd(x: &mut Limb, y: Limb) -> bool {
|
||||
let t = add(*x, y);
|
||||
*x = t.0;
|
||||
t.1
|
||||
}
|
||||
|
||||
// SUBTRACTION
|
||||
|
||||
/// Subtract two small integers and return the resulting value and if overflow happens.
|
||||
#[inline]
|
||||
pub fn sub(x: Limb, y: Limb) -> (Limb, bool) {
|
||||
x.overflowing_sub(y)
|
||||
}
|
||||
|
||||
/// SubAssign two small integers and return if overflow happens.
|
||||
#[inline]
|
||||
pub fn isub(x: &mut Limb, y: Limb) -> bool {
|
||||
let t = sub(*x, y);
|
||||
*x = t.0;
|
||||
t.1
|
||||
}
|
||||
|
||||
// MULTIPLICATION
|
||||
|
||||
/// Multiply two small integers (with carry) (and return the overflow contribution).
|
||||
///
|
||||
/// Returns the (low, high) components.
|
||||
#[inline]
|
||||
pub fn mul(x: Limb, y: Limb, carry: Limb) -> (Limb, Limb) {
|
||||
// Cannot overflow, as long as wide is 2x as wide. This is because
|
||||
// the following is always true:
|
||||
// `Wide::max_value() - (Narrow::max_value() * Narrow::max_value()) >= Narrow::max_value()`
|
||||
let z: Wide = as_wide(x) * as_wide(y) + as_wide(carry);
|
||||
let bits = mem::size_of::<Limb>() * 8;
|
||||
(as_limb(z), as_limb(z >> bits))
|
||||
}
|
||||
|
||||
/// Multiply two small integers (with carry) (and return if overflow happens).
|
||||
#[inline]
|
||||
pub fn imul(x: &mut Limb, y: Limb, carry: Limb) -> Limb {
|
||||
let t = mul(*x, y, carry);
|
||||
*x = t.0;
|
||||
t.1
|
||||
}
|
||||
} // scalar
|
||||
|
||||
// SMALL
|
||||
// -----
|
||||
|
||||
// Large-to-small operations, to modify a big integer from a native scalar.
|
||||
|
||||
mod small {
|
||||
use super::*;
|
||||
|
||||
// MULTIPLICATIION
|
||||
|
||||
/// ADDITION
|
||||
|
||||
/// Implied AddAssign implementation for adding a small integer to bigint.
|
||||
///
|
||||
/// Allows us to choose a start-index in x to store, to allow incrementing
|
||||
/// from a non-zero start.
|
||||
#[inline]
|
||||
pub fn iadd_impl(x: &mut Vec<Limb>, y: Limb, xstart: usize) {
|
||||
if x.len() <= xstart {
|
||||
x.push(y);
|
||||
} else {
|
||||
// Initial add
|
||||
let mut carry = scalar::iadd(&mut x[xstart], y);
|
||||
|
||||
// Increment until overflow stops occurring.
|
||||
let mut size = xstart + 1;
|
||||
while carry && size < x.len() {
|
||||
carry = scalar::iadd(&mut x[size], 1);
|
||||
size += 1;
|
||||
}
|
||||
|
||||
// If we overflowed the buffer entirely, need to add 1 to the end
|
||||
// of the buffer.
|
||||
if carry {
|
||||
x.push(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// AddAssign small integer to bigint.
|
||||
#[inline]
|
||||
pub fn iadd(x: &mut Vec<Limb>, y: Limb) {
|
||||
iadd_impl(x, y, 0);
|
||||
}
|
||||
|
||||
// SUBTRACTION
|
||||
|
||||
/// SubAssign small integer to bigint.
|
||||
/// Does not do overflowing subtraction.
|
||||
#[inline]
|
||||
pub fn isub_impl(x: &mut Vec<Limb>, y: Limb, xstart: usize) {
|
||||
debug_assert!(x.len() > xstart && (x[xstart] >= y || x.len() > xstart + 1));
|
||||
|
||||
// Initial subtraction
|
||||
let mut carry = scalar::isub(&mut x[xstart], y);
|
||||
|
||||
// Increment until overflow stops occurring.
|
||||
let mut size = xstart + 1;
|
||||
while carry && size < x.len() {
|
||||
carry = scalar::isub(&mut x[size], 1);
|
||||
size += 1;
|
||||
}
|
||||
normalize(x);
|
||||
}
|
||||
|
||||
// MULTIPLICATION
|
||||
|
||||
/// MulAssign small integer to bigint.
|
||||
#[inline]
|
||||
pub fn imul(x: &mut Vec<Limb>, y: Limb) {
|
||||
// Multiply iteratively over all elements, adding the carry each time.
|
||||
let mut carry: Limb = 0;
|
||||
for xi in &mut *x {
|
||||
carry = scalar::imul(xi, y, carry);
|
||||
}
|
||||
|
||||
// Overflow of value, add to end.
|
||||
if carry != 0 {
|
||||
x.push(carry);
|
||||
}
|
||||
}
|
||||
|
||||
/// Mul small integer to bigint.
|
||||
#[inline]
|
||||
pub fn mul(x: &[Limb], y: Limb) -> Vec<Limb> {
|
||||
let mut z = Vec::<Limb>::default();
|
||||
z.extend_from_slice(x);
|
||||
imul(&mut z, y);
|
||||
z
|
||||
}
|
||||
|
||||
/// MulAssign by a power.
|
||||
///
|
||||
/// Theoretically...
|
||||
///
|
||||
/// Use an exponentiation by squaring method, since it reduces the time
|
||||
/// complexity of the multiplication to ~`O(log(n))` for the squaring,
|
||||
/// and `O(n*m)` for the result. Since `m` is typically a lower-order
|
||||
/// factor, this significantly reduces the number of multiplications
|
||||
/// we need to do. Iteratively multiplying by small powers follows
|
||||
/// the nth triangular number series, which scales as `O(p^2)`, but
|
||||
/// where `p` is `n+m`. In short, it scales very poorly.
|
||||
///
|
||||
/// Practically....
|
||||
///
|
||||
/// Exponentiation by Squaring:
|
||||
/// running 2 tests
|
||||
/// test bigcomp_f32_lexical ... bench: 1,018 ns/iter (+/- 78)
|
||||
/// test bigcomp_f64_lexical ... bench: 3,639 ns/iter (+/- 1,007)
|
||||
///
|
||||
/// Exponentiation by Iterative Small Powers:
|
||||
/// running 2 tests
|
||||
/// test bigcomp_f32_lexical ... bench: 518 ns/iter (+/- 31)
|
||||
/// test bigcomp_f64_lexical ... bench: 583 ns/iter (+/- 47)
|
||||
///
|
||||
/// Exponentiation by Iterative Large Powers (of 2):
|
||||
/// running 2 tests
|
||||
/// test bigcomp_f32_lexical ... bench: 671 ns/iter (+/- 31)
|
||||
/// test bigcomp_f64_lexical ... bench: 1,394 ns/iter (+/- 47)
|
||||
///
|
||||
/// Even using worst-case scenarios, exponentiation by squaring is
|
||||
/// significantly slower for our workloads. Just multiply by small powers,
|
||||
/// in simple cases, and use precalculated large powers in other cases.
|
||||
pub fn imul_pow5(x: &mut Vec<Limb>, n: u32) {
|
||||
use super::large::KARATSUBA_CUTOFF;
|
||||
|
||||
let small_powers = POW5_LIMB;
|
||||
let large_powers = large_powers::POW5;
|
||||
|
||||
if n == 0 {
|
||||
// No exponent, just return.
|
||||
// The 0-index of the large powers is `2^0`, which is 1, so we want
|
||||
// to make sure we don't take that path with a literal 0.
|
||||
return;
|
||||
}
|
||||
|
||||
// We want to use the asymptotically faster algorithm if we're going
|
||||
// to be using Karabatsu multiplication sometime during the result,
|
||||
// otherwise, just use exponentiation by squaring.
|
||||
let bit_length = 32 - n.leading_zeros() as usize;
|
||||
debug_assert!(bit_length != 0 && bit_length <= large_powers.len());
|
||||
if x.len() + large_powers[bit_length - 1].len() < 2 * KARATSUBA_CUTOFF {
|
||||
// We can use iterative small powers to make this faster for the
|
||||
// easy cases.
|
||||
|
||||
// Multiply by the largest small power until n < step.
|
||||
let step = small_powers.len() - 1;
|
||||
let power = small_powers[step];
|
||||
let mut n = n as usize;
|
||||
while n >= step {
|
||||
imul(x, power);
|
||||
n -= step;
|
||||
}
|
||||
|
||||
// Multiply by the remainder.
|
||||
imul(x, small_powers[n]);
|
||||
} else {
|
||||
// In theory, this code should be asymptotically a lot faster,
|
||||
// in practice, our small::imul seems to be the limiting step,
|
||||
// and large imul is slow as well.
|
||||
|
||||
// Multiply by higher order powers.
|
||||
let mut idx: usize = 0;
|
||||
let mut bit: usize = 1;
|
||||
let mut n = n as usize;
|
||||
while n != 0 {
|
||||
if n & bit != 0 {
|
||||
debug_assert!(idx < large_powers.len());
|
||||
large::imul(x, large_powers[idx]);
|
||||
n ^= bit;
|
||||
}
|
||||
idx += 1;
|
||||
bit <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BIT LENGTH
|
||||
|
||||
/// Get number of leading zero bits in the storage.
|
||||
#[inline]
|
||||
pub fn leading_zeros(x: &[Limb]) -> usize {
|
||||
x.last().map_or(0, |x| x.leading_zeros() as usize)
|
||||
}
|
||||
|
||||
/// Calculate the bit-length of the big-integer.
|
||||
#[inline]
|
||||
pub fn bit_length(x: &[Limb]) -> usize {
|
||||
let bits = mem::size_of::<Limb>() * 8;
|
||||
// Avoid overflowing, calculate via total number of bits
|
||||
// minus leading zero bits.
|
||||
let nlz = leading_zeros(x);
|
||||
bits.checked_mul(x.len())
|
||||
.map_or_else(usize::max_value, |v| v - nlz)
|
||||
}
|
||||
|
||||
// SHL
|
||||
|
||||
/// Shift-left bits inside a buffer.
|
||||
///
|
||||
/// Assumes `n < Limb::BITS`, IE, internally shifting bits.
|
||||
#[inline]
|
||||
pub fn ishl_bits(x: &mut Vec<Limb>, n: usize) {
|
||||
// Need to shift by the number of `bits % Limb::BITS)`.
|
||||
let bits = mem::size_of::<Limb>() * 8;
|
||||
debug_assert!(n < bits);
|
||||
if n == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Internally, for each item, we shift left by n, and add the previous
|
||||
// right shifted limb-bits.
|
||||
// For example, we transform (for u8) shifted left 2, to:
|
||||
// b10100100 b01000010
|
||||
// b10 b10010001 b00001000
|
||||
let rshift = bits - n;
|
||||
let lshift = n;
|
||||
let mut prev: Limb = 0;
|
||||
for xi in &mut *x {
|
||||
let tmp = *xi;
|
||||
*xi <<= lshift;
|
||||
*xi |= prev >> rshift;
|
||||
prev = tmp;
|
||||
}
|
||||
|
||||
// Always push the carry, even if it creates a non-normal result.
|
||||
let carry = prev >> rshift;
|
||||
if carry != 0 {
|
||||
x.push(carry);
|
||||
}
|
||||
}
|
||||
|
||||
/// Shift-left `n` digits inside a buffer.
|
||||
///
|
||||
/// Assumes `n` is not 0.
|
||||
#[inline]
|
||||
pub fn ishl_limbs(x: &mut Vec<Limb>, n: usize) {
|
||||
debug_assert!(n != 0);
|
||||
if !x.is_empty() {
|
||||
x.reserve(n);
|
||||
x.splice(..0, iter::repeat(0).take(n));
|
||||
}
|
||||
}
|
||||
|
||||
/// Shift-left buffer by n bits.
|
||||
#[inline]
|
||||
pub fn ishl(x: &mut Vec<Limb>, n: usize) {
|
||||
let bits = mem::size_of::<Limb>() * 8;
|
||||
// Need to pad with zeros for the number of `bits / Limb::BITS`,
|
||||
// and shift-left with carry for `bits % Limb::BITS`.
|
||||
let rem = n % bits;
|
||||
let div = n / bits;
|
||||
ishl_bits(x, rem);
|
||||
if div != 0 {
|
||||
ishl_limbs(x, div);
|
||||
}
|
||||
}
|
||||
|
||||
// NORMALIZE
|
||||
|
||||
/// Normalize the container by popping any leading zeros.
|
||||
#[inline]
|
||||
pub fn normalize(x: &mut Vec<Limb>) {
|
||||
// Remove leading zero if we cause underflow. Since we're dividing
|
||||
// by a small power, we have at max 1 int removed.
|
||||
while x.last() == Some(&0) {
|
||||
x.pop();
|
||||
}
|
||||
}
|
||||
} // small
|
||||
|
||||
// LARGE
|
||||
// -----
|
||||
|
||||
// Large-to-large operations, to modify a big integer from a native scalar.
|
||||
|
||||
mod large {
|
||||
use super::*;
|
||||
|
||||
// RELATIVE OPERATORS
|
||||
|
||||
/// Compare `x` to `y`, in little-endian order.
|
||||
#[inline]
|
||||
pub fn compare(x: &[Limb], y: &[Limb]) -> cmp::Ordering {
|
||||
if x.len() > y.len() {
|
||||
cmp::Ordering::Greater
|
||||
} else if x.len() < y.len() {
|
||||
cmp::Ordering::Less
|
||||
} else {
|
||||
let iter = x.iter().rev().zip(y.iter().rev());
|
||||
for (&xi, &yi) in iter {
|
||||
if xi > yi {
|
||||
return cmp::Ordering::Greater;
|
||||
} else if xi < yi {
|
||||
return cmp::Ordering::Less;
|
||||
}
|
||||
}
|
||||
// Equal case.
|
||||
cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if x is less than y.
|
||||
#[inline]
|
||||
pub fn less(x: &[Limb], y: &[Limb]) -> bool {
|
||||
compare(x, y) == cmp::Ordering::Less
|
||||
}
|
||||
|
||||
/// Check if x is greater than or equal to y.
|
||||
#[inline]
|
||||
pub fn greater_equal(x: &[Limb], y: &[Limb]) -> bool {
|
||||
!less(x, y)
|
||||
}
|
||||
|
||||
// ADDITION
|
||||
|
||||
/// Implied AddAssign implementation for bigints.
|
||||
///
|
||||
/// Allows us to choose a start-index in x to store, so we can avoid
|
||||
/// padding the buffer with zeros when not needed, optimized for vectors.
|
||||
pub fn iadd_impl(x: &mut Vec<Limb>, y: &[Limb], xstart: usize) {
|
||||
// The effective x buffer is from `xstart..x.len()`, so we need to treat
|
||||
// that as the current range. If the effective y buffer is longer, need
|
||||
// to resize to that, + the start index.
|
||||
if y.len() > x.len() - xstart {
|
||||
x.resize(y.len() + xstart, 0);
|
||||
}
|
||||
|
||||
// Iteratively add elements from y to x.
|
||||
let mut carry = false;
|
||||
for (xi, yi) in x[xstart..].iter_mut().zip(y.iter()) {
|
||||
// Only one op of the two can overflow, since we added at max
|
||||
// Limb::max_value() + Limb::max_value(). Add the previous carry,
|
||||
// and store the current carry for the next.
|
||||
let mut tmp = scalar::iadd(xi, *yi);
|
||||
if carry {
|
||||
tmp |= scalar::iadd(xi, 1);
|
||||
}
|
||||
carry = tmp;
|
||||
}
|
||||
|
||||
// Overflow from the previous bit.
|
||||
if carry {
|
||||
small::iadd_impl(x, 1, y.len() + xstart);
|
||||
}
|
||||
}
|
||||
|
||||
/// AddAssign bigint to bigint.
|
||||
#[inline]
|
||||
pub fn iadd(x: &mut Vec<Limb>, y: &[Limb]) {
|
||||
iadd_impl(x, y, 0);
|
||||
}
|
||||
|
||||
/// Add bigint to bigint.
|
||||
#[inline]
|
||||
pub fn add(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
|
||||
let mut z = Vec::<Limb>::default();
|
||||
z.extend_from_slice(x);
|
||||
iadd(&mut z, y);
|
||||
z
|
||||
}
|
||||
|
||||
// SUBTRACTION
|
||||
|
||||
/// SubAssign bigint to bigint.
|
||||
pub fn isub(x: &mut Vec<Limb>, y: &[Limb]) {
|
||||
// Basic underflow checks.
|
||||
debug_assert!(greater_equal(x, y));
|
||||
|
||||
// Iteratively add elements from y to x.
|
||||
let mut carry = false;
|
||||
for (xi, yi) in x.iter_mut().zip(y.iter()) {
|
||||
// Only one op of the two can overflow, since we added at max
|
||||
// Limb::max_value() + Limb::max_value(). Add the previous carry,
|
||||
// and store the current carry for the next.
|
||||
let mut tmp = scalar::isub(xi, *yi);
|
||||
if carry {
|
||||
tmp |= scalar::isub(xi, 1);
|
||||
}
|
||||
carry = tmp;
|
||||
}
|
||||
|
||||
if carry {
|
||||
small::isub_impl(x, 1, y.len());
|
||||
} else {
|
||||
small::normalize(x);
|
||||
}
|
||||
}
|
||||
|
||||
// MULTIPLICATION
|
||||
|
||||
/// Number of digits to bottom-out to asymptotically slow algorithms.
|
||||
///
|
||||
/// Karatsuba tends to out-perform long-multiplication at ~320-640 bits,
|
||||
/// so we go halfway, while Newton division tends to out-perform
|
||||
/// Algorithm D at ~1024 bits. We can toggle this for optimal performance.
|
||||
pub const KARATSUBA_CUTOFF: usize = 32;
|
||||
|
||||
/// Grade-school multiplication algorithm.
|
||||
///
|
||||
/// Slow, naive algorithm, using limb-bit bases and just shifting left for
|
||||
/// each iteration. This could be optimized with numerous other algorithms,
|
||||
/// but it's extremely simple, and works in O(n*m) time, which is fine
|
||||
/// by me. Each iteration, of which there are `m` iterations, requires
|
||||
/// `n` multiplications, and `n` additions, or grade-school multiplication.
|
||||
fn long_mul(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
|
||||
// Using the immutable value, multiply by all the scalars in y, using
|
||||
// the algorithm defined above. Use a single buffer to avoid
|
||||
// frequent reallocations. Handle the first case to avoid a redundant
|
||||
// addition, since we know y.len() >= 1.
|
||||
let mut z: Vec<Limb> = small::mul(x, y[0]);
|
||||
z.resize(x.len() + y.len(), 0);
|
||||
|
||||
// Handle the iterative cases.
|
||||
for (i, &yi) in y[1..].iter().enumerate() {
|
||||
let zi: Vec<Limb> = small::mul(x, yi);
|
||||
iadd_impl(&mut z, &zi, i + 1);
|
||||
}
|
||||
|
||||
small::normalize(&mut z);
|
||||
|
||||
z
|
||||
}
|
||||
|
||||
/// Split two buffers into halfway, into (lo, hi).
|
||||
#[inline]
|
||||
pub fn karatsuba_split(z: &[Limb], m: usize) -> (&[Limb], &[Limb]) {
|
||||
(&z[..m], &z[m..])
|
||||
}
|
||||
|
||||
/// Karatsuba multiplication algorithm with roughly equal input sizes.
|
||||
///
|
||||
/// Assumes `y.len() >= x.len()`.
|
||||
fn karatsuba_mul(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
|
||||
if y.len() <= KARATSUBA_CUTOFF {
|
||||
// Bottom-out to long division for small cases.
|
||||
long_mul(x, y)
|
||||
} else if x.len() < y.len() / 2 {
|
||||
karatsuba_uneven_mul(x, y)
|
||||
} else {
|
||||
// Do our 3 multiplications.
|
||||
let m = y.len() / 2;
|
||||
let (xl, xh) = karatsuba_split(x, m);
|
||||
let (yl, yh) = karatsuba_split(y, m);
|
||||
let sumx = add(xl, xh);
|
||||
let sumy = add(yl, yh);
|
||||
let z0 = karatsuba_mul(xl, yl);
|
||||
let mut z1 = karatsuba_mul(&sumx, &sumy);
|
||||
let z2 = karatsuba_mul(xh, yh);
|
||||
// Properly scale z1, which is `z1 - z2 - zo`.
|
||||
isub(&mut z1, &z2);
|
||||
isub(&mut z1, &z0);
|
||||
|
||||
// Create our result, which is equal to, in little-endian order:
|
||||
// [z0, z1 - z2 - z0, z2]
|
||||
// z1 must be shifted m digits (2^(32m)) over.
|
||||
// z2 must be shifted 2*m digits (2^(64m)) over.
|
||||
let len = z0.len().max(m + z1.len()).max(2 * m + z2.len());
|
||||
let mut result = z0;
|
||||
result.reserve_exact(len - result.len());
|
||||
iadd_impl(&mut result, &z1, m);
|
||||
iadd_impl(&mut result, &z2, 2 * m);
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// Karatsuba multiplication algorithm where y is substantially larger than x.
|
||||
///
|
||||
/// Assumes `y.len() >= x.len()`.
|
||||
fn karatsuba_uneven_mul(x: &[Limb], mut y: &[Limb]) -> Vec<Limb> {
|
||||
let mut result = Vec::<Limb>::default();
|
||||
result.resize(x.len() + y.len(), 0);
|
||||
|
||||
// This effectively is like grade-school multiplication between
|
||||
// two numbers, except we're using splits on `y`, and the intermediate
|
||||
// step is a Karatsuba multiplication.
|
||||
let mut start = 0;
|
||||
while !y.is_empty() {
|
||||
let m = x.len().min(y.len());
|
||||
let (yl, yh) = karatsuba_split(y, m);
|
||||
let prod = karatsuba_mul(x, yl);
|
||||
iadd_impl(&mut result, &prod, start);
|
||||
y = yh;
|
||||
start += m;
|
||||
}
|
||||
small::normalize(&mut result);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Forwarder to the proper Karatsuba algorithm.
|
||||
#[inline]
|
||||
fn karatsuba_mul_fwd(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
|
||||
if x.len() < y.len() {
|
||||
karatsuba_mul(x, y)
|
||||
} else {
|
||||
karatsuba_mul(y, x)
|
||||
}
|
||||
}
|
||||
|
||||
/// MulAssign bigint to bigint.
|
||||
#[inline]
|
||||
pub fn imul(x: &mut Vec<Limb>, y: &[Limb]) {
|
||||
if y.len() == 1 {
|
||||
small::imul(x, y[0]);
|
||||
} else {
|
||||
// We're not really in a condition where using Karatsuba
|
||||
// multiplication makes sense, so we're just going to use long
|
||||
// division. ~20% speedup compared to:
|
||||
// *x = karatsuba_mul_fwd(x, y);
|
||||
*x = karatsuba_mul_fwd(x, y);
|
||||
}
|
||||
}
|
||||
} // large
|
||||
|
||||
// TRAITS
|
||||
// ------
|
||||
|
||||
/// Traits for shared operations for big integers.
|
||||
///
|
||||
/// None of these are implemented using normal traits, since these
|
||||
/// are very expensive operations, and we want to deliberately
|
||||
/// and explicitly use these functions.
|
||||
pub(crate) trait Math: Clone + Sized + Default {
|
||||
// DATA
|
||||
|
||||
/// Get access to the underlying data
|
||||
fn data(&self) -> &Vec<Limb>;
|
||||
|
||||
/// Get access to the underlying data
|
||||
fn data_mut(&mut self) -> &mut Vec<Limb>;
|
||||
|
||||
// RELATIVE OPERATIONS
|
||||
|
||||
/// Compare self to y.
|
||||
#[inline]
|
||||
fn compare(&self, y: &Self) -> cmp::Ordering {
|
||||
large::compare(self.data(), y.data())
|
||||
}
|
||||
|
||||
// PROPERTIES
|
||||
|
||||
/// Get the high 64-bits from the bigint and if there are remaining bits.
|
||||
#[inline]
|
||||
fn hi64(&self) -> (u64, bool) {
|
||||
self.data().as_slice().hi64()
|
||||
}
|
||||
|
||||
/// Calculate the bit-length of the big-integer.
|
||||
/// Returns usize::max_value() if the value overflows,
|
||||
/// IE, if `self.data().len() > usize::max_value() / 8`.
|
||||
#[inline]
|
||||
fn bit_length(&self) -> usize {
|
||||
small::bit_length(self.data())
|
||||
}
|
||||
|
||||
// INTEGER CONVERSIONS
|
||||
|
||||
/// Create new big integer from u64.
|
||||
#[inline]
|
||||
fn from_u64(x: u64) -> Self {
|
||||
let mut v = Self::default();
|
||||
let slc = split_u64(x);
|
||||
v.data_mut().extend_from_slice(&slc);
|
||||
v.normalize();
|
||||
v
|
||||
}
|
||||
|
||||
// NORMALIZE
|
||||
|
||||
/// Normalize the integer, so any leading zero values are removed.
|
||||
#[inline]
|
||||
fn normalize(&mut self) {
|
||||
small::normalize(self.data_mut());
|
||||
}
|
||||
|
||||
// ADDITION
|
||||
|
||||
/// AddAssign small integer.
|
||||
#[inline]
|
||||
fn iadd_small(&mut self, y: Limb) {
|
||||
small::iadd(self.data_mut(), y);
|
||||
}
|
||||
|
||||
// MULTIPLICATION
|
||||
|
||||
/// MulAssign small integer.
|
||||
#[inline]
|
||||
fn imul_small(&mut self, y: Limb) {
|
||||
small::imul(self.data_mut(), y);
|
||||
}
|
||||
|
||||
/// Multiply by a power of 2.
|
||||
#[inline]
|
||||
fn imul_pow2(&mut self, n: u32) {
|
||||
self.ishl(n as usize);
|
||||
}
|
||||
|
||||
/// Multiply by a power of 5.
|
||||
#[inline]
|
||||
fn imul_pow5(&mut self, n: u32) {
|
||||
small::imul_pow5(self.data_mut(), n);
|
||||
}
|
||||
|
||||
/// MulAssign by a power of 10.
|
||||
#[inline]
|
||||
fn imul_pow10(&mut self, n: u32) {
|
||||
self.imul_pow5(n);
|
||||
self.imul_pow2(n);
|
||||
}
|
||||
|
||||
// SHIFTS
|
||||
|
||||
/// Shift-left the entire buffer n bits.
|
||||
#[inline]
|
||||
fn ishl(&mut self, n: usize) {
|
||||
small::ishl(self.data_mut(), n);
|
||||
}
|
||||
}
|
38
vendor/serde_json/src/lexical/mod.rs
vendored
Normal file
38
vendor/serde_json/src/lexical/mod.rs
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// The code in this module is derived from the `lexical` crate by @Alexhuszagh
|
||||
// which the author condensed into this minimal subset for use in serde_json.
|
||||
// For the serde_json use case we care more about reliably round tripping all
|
||||
// possible floating point values than about parsing any arbitrarily long string
|
||||
// of digits with perfect accuracy, as the latter would take a high cost in
|
||||
// compile time and performance.
|
||||
//
|
||||
// Dual licensed as MIT and Apache 2.0 just like the rest of serde_json, but
|
||||
// copyright Alexander Huszagh.
|
||||
|
||||
//! Fast, minimal float-parsing algorithm.
|
||||
|
||||
// MODULES
|
||||
pub(crate) mod algorithm;
|
||||
mod bhcomp;
|
||||
mod bignum;
|
||||
mod cached;
|
||||
mod cached_float80;
|
||||
mod digit;
|
||||
mod errors;
|
||||
pub(crate) mod exponent;
|
||||
pub(crate) mod float;
|
||||
mod large_powers;
|
||||
pub(crate) mod math;
|
||||
pub(crate) mod num;
|
||||
pub(crate) mod parse;
|
||||
pub(crate) mod rounding;
|
||||
mod shift;
|
||||
mod small_powers;
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
mod large_powers32;
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
mod large_powers64;
|
||||
|
||||
// API
|
||||
pub use self::parse::{parse_concise_float, parse_truncated_float};
|
440
vendor/serde_json/src/lexical/num.rs
vendored
Normal file
440
vendor/serde_json/src/lexical/num.rs
vendored
Normal file
@ -0,0 +1,440 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Utilities for Rust numbers.
|
||||
|
||||
use core::ops;
|
||||
|
||||
/// Precalculated values of radix**i for i in range [0, arr.len()-1].
|
||||
/// Each value can be **exactly** represented as that type.
|
||||
const F32_POW10: [f32; 11] = [
|
||||
1.0,
|
||||
10.0,
|
||||
100.0,
|
||||
1000.0,
|
||||
10000.0,
|
||||
100000.0,
|
||||
1000000.0,
|
||||
10000000.0,
|
||||
100000000.0,
|
||||
1000000000.0,
|
||||
10000000000.0,
|
||||
];
|
||||
|
||||
/// Precalculated values of radix**i for i in range [0, arr.len()-1].
|
||||
/// Each value can be **exactly** represented as that type.
|
||||
const F64_POW10: [f64; 23] = [
|
||||
1.0,
|
||||
10.0,
|
||||
100.0,
|
||||
1000.0,
|
||||
10000.0,
|
||||
100000.0,
|
||||
1000000.0,
|
||||
10000000.0,
|
||||
100000000.0,
|
||||
1000000000.0,
|
||||
10000000000.0,
|
||||
100000000000.0,
|
||||
1000000000000.0,
|
||||
10000000000000.0,
|
||||
100000000000000.0,
|
||||
1000000000000000.0,
|
||||
10000000000000000.0,
|
||||
100000000000000000.0,
|
||||
1000000000000000000.0,
|
||||
10000000000000000000.0,
|
||||
100000000000000000000.0,
|
||||
1000000000000000000000.0,
|
||||
10000000000000000000000.0,
|
||||
];
|
||||
|
||||
/// Type that can be converted to primitive with `as`.
|
||||
pub trait AsPrimitive: Sized + Copy + PartialOrd {
|
||||
fn as_u32(self) -> u32;
|
||||
fn as_u64(self) -> u64;
|
||||
fn as_u128(self) -> u128;
|
||||
fn as_usize(self) -> usize;
|
||||
fn as_f32(self) -> f32;
|
||||
fn as_f64(self) -> f64;
|
||||
}
|
||||
|
||||
macro_rules! as_primitive_impl {
|
||||
($($ty:ident)*) => {
|
||||
$(
|
||||
impl AsPrimitive for $ty {
|
||||
#[inline]
|
||||
fn as_u32(self) -> u32 {
|
||||
self as u32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_u64(self) -> u64 {
|
||||
self as u64
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_u128(self) -> u128 {
|
||||
self as u128
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_usize(self) -> usize {
|
||||
self as usize
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_f32(self) -> f32 {
|
||||
self as f32
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_f64(self) -> f64 {
|
||||
self as f64
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
as_primitive_impl! { u32 u64 u128 usize f32 f64 }
|
||||
|
||||
/// An interface for casting between machine scalars.
|
||||
pub trait AsCast: AsPrimitive {
|
||||
/// Creates a number from another value that can be converted into
|
||||
/// a primitive via the `AsPrimitive` trait.
|
||||
fn as_cast<N: AsPrimitive>(n: N) -> Self;
|
||||
}
|
||||
|
||||
macro_rules! as_cast_impl {
|
||||
($ty:ident, $method:ident) => {
|
||||
impl AsCast for $ty {
|
||||
#[inline]
|
||||
fn as_cast<N: AsPrimitive>(n: N) -> Self {
|
||||
n.$method()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
as_cast_impl!(u32, as_u32);
|
||||
as_cast_impl!(u64, as_u64);
|
||||
as_cast_impl!(u128, as_u128);
|
||||
as_cast_impl!(usize, as_usize);
|
||||
as_cast_impl!(f32, as_f32);
|
||||
as_cast_impl!(f64, as_f64);
|
||||
|
||||
/// Numerical type trait.
|
||||
pub trait Number: AsCast + ops::Add<Output = Self> {}
|
||||
|
||||
macro_rules! number_impl {
|
||||
($($ty:ident)*) => {
|
||||
$(
|
||||
impl Number for $ty {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
number_impl! { u32 u64 u128 usize f32 f64 }
|
||||
|
||||
/// Defines a trait that supports integral operations.
|
||||
pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> {
|
||||
const ZERO: Self;
|
||||
}
|
||||
|
||||
macro_rules! integer_impl {
|
||||
($($ty:tt)*) => {
|
||||
$(
|
||||
impl Integer for $ty {
|
||||
const ZERO: Self = 0;
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
integer_impl! { u32 u64 u128 usize }
|
||||
|
||||
/// Type trait for the mantissa type.
|
||||
pub trait Mantissa: Integer {
|
||||
/// Mask to extract the high bits from the integer.
|
||||
const HIMASK: Self;
|
||||
/// Mask to extract the low bits from the integer.
|
||||
const LOMASK: Self;
|
||||
/// Full size of the integer, in bits.
|
||||
const FULL: i32;
|
||||
/// Half size of the integer, in bits.
|
||||
const HALF: i32 = Self::FULL / 2;
|
||||
}
|
||||
|
||||
impl Mantissa for u64 {
|
||||
const HIMASK: u64 = 0xFFFFFFFF00000000;
|
||||
const LOMASK: u64 = 0x00000000FFFFFFFF;
|
||||
const FULL: i32 = 64;
|
||||
}
|
||||
|
||||
/// Get exact exponent limit for radix.
|
||||
pub trait Float: Number {
|
||||
/// Unsigned type of the same size.
|
||||
type Unsigned: Integer;
|
||||
|
||||
/// Literal zero.
|
||||
const ZERO: Self;
|
||||
/// Maximum number of digits that can contribute in the mantissa.
|
||||
///
|
||||
/// We can exactly represent a float in radix `b` from radix 2 if
|
||||
/// `b` is divisible by 2. This function calculates the exact number of
|
||||
/// digits required to exactly represent that float.
|
||||
///
|
||||
/// According to the "Handbook of Floating Point Arithmetic",
|
||||
/// for IEEE754, with emin being the min exponent, p2 being the
|
||||
/// precision, and b being the radix, the number of digits follows as:
|
||||
///
|
||||
/// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
|
||||
///
|
||||
/// For f32, this follows as:
|
||||
/// emin = -126
|
||||
/// p2 = 24
|
||||
///
|
||||
/// For f64, this follows as:
|
||||
/// emin = -1022
|
||||
/// p2 = 53
|
||||
///
|
||||
/// In Python:
|
||||
/// `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))`
|
||||
///
|
||||
/// This was used to calculate the maximum number of digits for [2, 36].
|
||||
const MAX_DIGITS: usize;
|
||||
|
||||
// MASKS
|
||||
|
||||
/// Bitmask for the sign bit.
|
||||
const SIGN_MASK: Self::Unsigned;
|
||||
/// Bitmask for the exponent, including the hidden bit.
|
||||
const EXPONENT_MASK: Self::Unsigned;
|
||||
/// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction.
|
||||
const HIDDEN_BIT_MASK: Self::Unsigned;
|
||||
/// Bitmask for the mantissa (fraction), excluding the hidden bit.
|
||||
const MANTISSA_MASK: Self::Unsigned;
|
||||
|
||||
// PROPERTIES
|
||||
|
||||
/// Positive infinity as bits.
|
||||
const INFINITY_BITS: Self::Unsigned;
|
||||
/// Positive infinity as bits.
|
||||
const NEGATIVE_INFINITY_BITS: Self::Unsigned;
|
||||
/// Size of the significand (mantissa) without hidden bit.
|
||||
const MANTISSA_SIZE: i32;
|
||||
/// Bias of the exponet
|
||||
const EXPONENT_BIAS: i32;
|
||||
/// Exponent portion of a denormal float.
|
||||
const DENORMAL_EXPONENT: i32;
|
||||
/// Maximum exponent value in float.
|
||||
const MAX_EXPONENT: i32;
|
||||
|
||||
// ROUNDING
|
||||
|
||||
/// Default number of bits to shift (or 64 - mantissa size - 1).
|
||||
const DEFAULT_SHIFT: i32;
|
||||
/// Mask to determine if a full-carry occurred (1 in bit above hidden bit).
|
||||
const CARRY_MASK: u64;
|
||||
|
||||
/// Get min and max exponent limits (exact) from radix.
|
||||
fn exponent_limit() -> (i32, i32);
|
||||
|
||||
/// Get the number of digits that can be shifted from exponent to mantissa.
|
||||
fn mantissa_limit() -> i32;
|
||||
|
||||
// Re-exported methods from std.
|
||||
fn pow10(self, n: i32) -> Self;
|
||||
fn from_bits(u: Self::Unsigned) -> Self;
|
||||
fn to_bits(self) -> Self::Unsigned;
|
||||
fn is_sign_positive(self) -> bool;
|
||||
fn is_sign_negative(self) -> bool;
|
||||
|
||||
/// Returns true if the float is a denormal.
|
||||
#[inline]
|
||||
fn is_denormal(self) -> bool {
|
||||
self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
|
||||
}
|
||||
|
||||
/// Returns true if the float is a NaN or Infinite.
|
||||
#[inline]
|
||||
fn is_special(self) -> bool {
|
||||
self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
|
||||
}
|
||||
|
||||
/// Returns true if the float is infinite.
|
||||
#[inline]
|
||||
fn is_inf(self) -> bool {
|
||||
self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
|
||||
}
|
||||
|
||||
/// Get exponent component from the float.
|
||||
#[inline]
|
||||
fn exponent(self) -> i32 {
|
||||
if self.is_denormal() {
|
||||
return Self::DENORMAL_EXPONENT;
|
||||
}
|
||||
|
||||
let bits = self.to_bits();
|
||||
let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32();
|
||||
biased_e as i32 - Self::EXPONENT_BIAS
|
||||
}
|
||||
|
||||
/// Get mantissa (significand) component from float.
|
||||
#[inline]
|
||||
fn mantissa(self) -> Self::Unsigned {
|
||||
let bits = self.to_bits();
|
||||
let s = bits & Self::MANTISSA_MASK;
|
||||
if !self.is_denormal() {
|
||||
s + Self::HIDDEN_BIT_MASK
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
/// Get next greater float for a positive float.
|
||||
/// Value must be >= 0.0 and < INFINITY.
|
||||
#[inline]
|
||||
fn next_positive(self) -> Self {
|
||||
debug_assert!(self.is_sign_positive() && !self.is_inf());
|
||||
Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32))
|
||||
}
|
||||
|
||||
/// Round a positive number to even.
|
||||
#[inline]
|
||||
fn round_positive_even(self) -> Self {
|
||||
if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) {
|
||||
self.next_positive()
|
||||
} else {
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Float for f32 {
|
||||
type Unsigned = u32;
|
||||
|
||||
const ZERO: f32 = 0.0;
|
||||
const MAX_DIGITS: usize = 114;
|
||||
const SIGN_MASK: u32 = 0x80000000;
|
||||
const EXPONENT_MASK: u32 = 0x7F800000;
|
||||
const HIDDEN_BIT_MASK: u32 = 0x00800000;
|
||||
const MANTISSA_MASK: u32 = 0x007FFFFF;
|
||||
const INFINITY_BITS: u32 = 0x7F800000;
|
||||
const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK;
|
||||
const MANTISSA_SIZE: i32 = 23;
|
||||
const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
|
||||
const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
|
||||
const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
|
||||
const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1;
|
||||
const CARRY_MASK: u64 = 0x1000000;
|
||||
|
||||
#[inline]
|
||||
fn exponent_limit() -> (i32, i32) {
|
||||
(-10, 10)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mantissa_limit() -> i32 {
|
||||
7
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn pow10(self, n: i32) -> f32 {
|
||||
// Check the exponent is within bounds in debug builds.
|
||||
debug_assert!({
|
||||
let (min, max) = Self::exponent_limit();
|
||||
n >= min && n <= max
|
||||
});
|
||||
|
||||
if n > 0 {
|
||||
self * F32_POW10[n as usize]
|
||||
} else {
|
||||
self / F32_POW10[-n as usize]
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_bits(u: u32) -> f32 {
|
||||
f32::from_bits(u)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_bits(self) -> u32 {
|
||||
f32::to_bits(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_sign_positive(self) -> bool {
|
||||
f32::is_sign_positive(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_sign_negative(self) -> bool {
|
||||
f32::is_sign_negative(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Float for f64 {
|
||||
type Unsigned = u64;
|
||||
|
||||
const ZERO: f64 = 0.0;
|
||||
const MAX_DIGITS: usize = 769;
|
||||
const SIGN_MASK: u64 = 0x8000000000000000;
|
||||
const EXPONENT_MASK: u64 = 0x7FF0000000000000;
|
||||
const HIDDEN_BIT_MASK: u64 = 0x0010000000000000;
|
||||
const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF;
|
||||
const INFINITY_BITS: u64 = 0x7FF0000000000000;
|
||||
const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK;
|
||||
const MANTISSA_SIZE: i32 = 52;
|
||||
const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
|
||||
const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
|
||||
const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
|
||||
const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1;
|
||||
const CARRY_MASK: u64 = 0x20000000000000;
|
||||
|
||||
#[inline]
|
||||
fn exponent_limit() -> (i32, i32) {
|
||||
(-22, 22)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mantissa_limit() -> i32 {
|
||||
15
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn pow10(self, n: i32) -> f64 {
|
||||
// Check the exponent is within bounds in debug builds.
|
||||
debug_assert!({
|
||||
let (min, max) = Self::exponent_limit();
|
||||
n >= min && n <= max
|
||||
});
|
||||
|
||||
if n > 0 {
|
||||
self * F64_POW10[n as usize]
|
||||
} else {
|
||||
self / F64_POW10[-n as usize]
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_bits(u: u64) -> f64 {
|
||||
f64::from_bits(u)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_bits(self) -> u64 {
|
||||
f64::to_bits(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_sign_positive(self) -> bool {
|
||||
f64::is_sign_positive(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_sign_negative(self) -> bool {
|
||||
f64::is_sign_negative(self)
|
||||
}
|
||||
}
|
83
vendor/serde_json/src/lexical/parse.rs
vendored
Normal file
83
vendor/serde_json/src/lexical/parse.rs
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use super::algorithm::*;
|
||||
use super::bhcomp::*;
|
||||
use super::digit::*;
|
||||
use super::exponent::*;
|
||||
use super::num::*;
|
||||
|
||||
// PARSERS
|
||||
// -------
|
||||
|
||||
/// Parse float for which the entire integer and fraction parts fit into a 64
|
||||
/// bit mantissa.
|
||||
pub fn parse_concise_float<F>(mantissa: u64, mant_exp: i32) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
if let Some(float) = fast_path(mantissa, mant_exp) {
|
||||
return float;
|
||||
}
|
||||
|
||||
// Moderate path (use an extended 80-bit representation).
|
||||
let truncated = false;
|
||||
let (fp, valid) = moderate_path::<F>(mantissa, mant_exp, truncated);
|
||||
if valid {
|
||||
return fp.into_float::<F>();
|
||||
}
|
||||
|
||||
let b = fp.into_downward_float::<F>();
|
||||
if b.is_special() {
|
||||
// We have a non-finite number, we get to leave early.
|
||||
return b;
|
||||
}
|
||||
|
||||
// Slow path, fast path didn't work.
|
||||
let mut buffer = itoa::Buffer::new();
|
||||
let integer = buffer.format(mantissa).as_bytes();
|
||||
let fraction = &[];
|
||||
bhcomp(b, integer, fraction, mant_exp)
|
||||
}
|
||||
|
||||
/// Parse float from extracted float components.
|
||||
///
|
||||
/// * `integer` - Slice containing the integer digits.
|
||||
/// * `fraction` - Slice containing the fraction digits.
|
||||
/// * `exponent` - Parsed, 32-bit exponent.
|
||||
///
|
||||
/// Precondition: The integer must not have leading zeros.
|
||||
pub fn parse_truncated_float<F>(integer: &[u8], mut fraction: &[u8], exponent: i32) -> F
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Trim trailing zeroes from the fraction part.
|
||||
while fraction.last() == Some(&b'0') {
|
||||
fraction = &fraction[..fraction.len() - 1];
|
||||
}
|
||||
|
||||
// Calculate the number of truncated digits.
|
||||
let mut truncated = 0;
|
||||
let mut mantissa: u64 = 0;
|
||||
let mut iter = integer.iter().chain(fraction);
|
||||
for &c in &mut iter {
|
||||
mantissa = match add_digit(mantissa, to_digit(c).unwrap()) {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
truncated = 1 + iter.count();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let mant_exp = mantissa_exponent(exponent, fraction.len(), truncated);
|
||||
let is_truncated = true;
|
||||
|
||||
fallback_path(
|
||||
integer,
|
||||
fraction,
|
||||
mantissa,
|
||||
exponent,
|
||||
mant_exp,
|
||||
is_truncated,
|
||||
)
|
||||
}
|
231
vendor/serde_json/src/lexical/rounding.rs
vendored
Normal file
231
vendor/serde_json/src/lexical/rounding.rs
vendored
Normal file
@ -0,0 +1,231 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Defines rounding schemes for floating-point numbers.
|
||||
|
||||
use super::float::ExtendedFloat;
|
||||
use super::num::*;
|
||||
use super::shift::*;
|
||||
use core::mem;
|
||||
|
||||
// MASKS
|
||||
|
||||
/// Calculate a scalar factor of 2 above the halfway point.
|
||||
#[inline]
|
||||
pub(crate) fn nth_bit(n: u64) -> u64 {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!(n < bits, "nth_bit() overflow in shl.");
|
||||
|
||||
1 << n
|
||||
}
|
||||
|
||||
/// Generate a bitwise mask for the lower `n` bits.
|
||||
#[inline]
|
||||
pub(crate) fn lower_n_mask(n: u64) -> u64 {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!(n <= bits, "lower_n_mask() overflow in shl.");
|
||||
|
||||
if n == bits {
|
||||
u64::max_value()
|
||||
} else {
|
||||
(1 << n) - 1
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the halfway point for the lower `n` bits.
|
||||
#[inline]
|
||||
pub(crate) fn lower_n_halfway(n: u64) -> u64 {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!(n <= bits, "lower_n_halfway() overflow in shl.");
|
||||
|
||||
if n == 0 {
|
||||
0
|
||||
} else {
|
||||
nth_bit(n - 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate a bitwise mask with `n` 1 bits starting at the `bit` position.
|
||||
#[inline]
|
||||
pub(crate) fn internal_n_mask(bit: u64, n: u64) -> u64 {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!(bit <= bits, "internal_n_halfway() overflow in shl.");
|
||||
debug_assert!(n <= bits, "internal_n_halfway() overflow in shl.");
|
||||
debug_assert!(bit >= n, "internal_n_halfway() overflow in sub.");
|
||||
|
||||
lower_n_mask(bit) ^ lower_n_mask(bit - n)
|
||||
}
|
||||
|
||||
// NEAREST ROUNDING
|
||||
|
||||
// Shift right N-bytes and round to the nearest.
|
||||
//
|
||||
// Return if we are above halfway and if we are halfway.
|
||||
#[inline]
|
||||
pub(crate) fn round_nearest(fp: &mut ExtendedFloat, shift: i32) -> (bool, bool) {
|
||||
// Extract the truncated bits using mask.
|
||||
// Calculate if the value of the truncated bits are either above
|
||||
// the mid-way point, or equal to it.
|
||||
//
|
||||
// For example, for 4 truncated bytes, the mask would be b1111
|
||||
// and the midway point would be b1000.
|
||||
let mask: u64 = lower_n_mask(shift as u64);
|
||||
let halfway: u64 = lower_n_halfway(shift as u64);
|
||||
|
||||
let truncated_bits = fp.mant & mask;
|
||||
let is_above = truncated_bits > halfway;
|
||||
let is_halfway = truncated_bits == halfway;
|
||||
|
||||
// Bit shift so the leading bit is in the hidden bit.
|
||||
overflowing_shr(fp, shift);
|
||||
|
||||
(is_above, is_halfway)
|
||||
}
|
||||
|
||||
// Tie rounded floating point to event.
|
||||
#[inline]
|
||||
pub(crate) fn tie_even(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) {
|
||||
// Extract the last bit after shifting (and determine if it is odd).
|
||||
let is_odd = fp.mant & 1 == 1;
|
||||
|
||||
// Calculate if we need to roundup.
|
||||
// We need to roundup if we are above halfway, or if we are odd
|
||||
// and at half-way (need to tie-to-even).
|
||||
if is_above || (is_odd && is_halfway) {
|
||||
fp.mant += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Shift right N-bytes and round nearest, tie-to-even.
|
||||
//
|
||||
// Floating-point arithmetic uses round to nearest, ties to even,
|
||||
// which rounds to the nearest value, if the value is halfway in between,
|
||||
// round to an even value.
|
||||
#[inline]
|
||||
pub(crate) fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32) {
|
||||
let (is_above, is_halfway) = round_nearest(fp, shift);
|
||||
tie_even(fp, is_above, is_halfway);
|
||||
}
|
||||
|
||||
// DIRECTED ROUNDING
|
||||
|
||||
// Shift right N-bytes and round towards a direction.
|
||||
//
|
||||
// Return if we have any truncated bytes.
|
||||
#[inline]
|
||||
fn round_toward(fp: &mut ExtendedFloat, shift: i32) -> bool {
|
||||
let mask: u64 = lower_n_mask(shift as u64);
|
||||
let truncated_bits = fp.mant & mask;
|
||||
|
||||
// Bit shift so the leading bit is in the hidden bit.
|
||||
overflowing_shr(fp, shift);
|
||||
|
||||
truncated_bits != 0
|
||||
}
|
||||
|
||||
// Round down.
|
||||
#[inline]
|
||||
fn downard(_: &mut ExtendedFloat, _: bool) {}
|
||||
|
||||
// Shift right N-bytes and round toward zero.
|
||||
//
|
||||
// Floating-point arithmetic defines round toward zero, which rounds
|
||||
// towards positive zero.
|
||||
#[inline]
|
||||
pub(crate) fn round_downward(fp: &mut ExtendedFloat, shift: i32) {
|
||||
// Bit shift so the leading bit is in the hidden bit.
|
||||
// No rounding schemes, so we just ignore everything else.
|
||||
let is_truncated = round_toward(fp, shift);
|
||||
downard(fp, is_truncated);
|
||||
}
|
||||
|
||||
// ROUND TO FLOAT
|
||||
|
||||
// Shift the ExtendedFloat fraction to the fraction bits in a native float.
|
||||
//
|
||||
// Floating-point arithmetic uses round to nearest, ties to even,
|
||||
// which rounds to the nearest value, if the value is halfway in between,
|
||||
// round to an even value.
|
||||
#[inline]
|
||||
pub(crate) fn round_to_float<F, Algorithm>(fp: &mut ExtendedFloat, algorithm: Algorithm)
|
||||
where
|
||||
F: Float,
|
||||
Algorithm: FnOnce(&mut ExtendedFloat, i32),
|
||||
{
|
||||
// Calculate the difference to allow a single calculation
|
||||
// rather than a loop, to minimize the number of ops required.
|
||||
// This does underflow detection.
|
||||
let final_exp = fp.exp + F::DEFAULT_SHIFT;
|
||||
if final_exp < F::DENORMAL_EXPONENT {
|
||||
// We would end up with a denormal exponent, try to round to more
|
||||
// digits. Only shift right if we can avoid zeroing out the value,
|
||||
// which requires the exponent diff to be < M::BITS. The value
|
||||
// is already normalized, so we shouldn't have any issue zeroing
|
||||
// out the value.
|
||||
let diff = F::DENORMAL_EXPONENT - fp.exp;
|
||||
if diff <= u64::FULL {
|
||||
// We can avoid underflow, can get a valid representation.
|
||||
algorithm(fp, diff);
|
||||
} else {
|
||||
// Certain underflow, assign literal 0s.
|
||||
fp.mant = 0;
|
||||
fp.exp = 0;
|
||||
}
|
||||
} else {
|
||||
algorithm(fp, F::DEFAULT_SHIFT);
|
||||
}
|
||||
|
||||
if fp.mant & F::CARRY_MASK == F::CARRY_MASK {
|
||||
// Roundup carried over to 1 past the hidden bit.
|
||||
shr(fp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// AVOID OVERFLOW/UNDERFLOW
|
||||
|
||||
// Avoid overflow for large values, shift left as needed.
|
||||
//
|
||||
// Shift until a 1-bit is in the hidden bit, if the mantissa is not 0.
|
||||
#[inline]
|
||||
pub(crate) fn avoid_overflow<F>(fp: &mut ExtendedFloat)
|
||||
where
|
||||
F: Float,
|
||||
{
|
||||
// Calculate the difference to allow a single calculation
|
||||
// rather than a loop, minimizing the number of ops required.
|
||||
if fp.exp >= F::MAX_EXPONENT {
|
||||
let diff = fp.exp - F::MAX_EXPONENT;
|
||||
if diff <= F::MANTISSA_SIZE {
|
||||
// Our overflow mask needs to start at the hidden bit, or at
|
||||
// `F::MANTISSA_SIZE+1`, and needs to have `diff+1` bits set,
|
||||
// to see if our value overflows.
|
||||
let bit = (F::MANTISSA_SIZE + 1) as u64;
|
||||
let n = (diff + 1) as u64;
|
||||
let mask = internal_n_mask(bit, n);
|
||||
if (fp.mant & mask) == 0 {
|
||||
// If we have no 1-bit in the hidden-bit position,
|
||||
// which is index 0, we need to shift 1.
|
||||
let shift = diff + 1;
|
||||
shl(fp, shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ROUND TO NATIVE
|
||||
|
||||
// Round an extended-precision float to a native float representation.
|
||||
#[inline]
|
||||
pub(crate) fn round_to_native<F, Algorithm>(fp: &mut ExtendedFloat, algorithm: Algorithm)
|
||||
where
|
||||
F: Float,
|
||||
Algorithm: FnOnce(&mut ExtendedFloat, i32),
|
||||
{
|
||||
// Shift all the way left, to ensure a consistent representation.
|
||||
// The following right-shifts do not work for a non-normalized number.
|
||||
fp.normalize();
|
||||
|
||||
// Round so the fraction is in a native mantissa representation,
|
||||
// and avoid overflow/underflow.
|
||||
round_to_float::<F, _>(fp, algorithm);
|
||||
avoid_overflow::<F>(fp);
|
||||
}
|
46
vendor/serde_json/src/lexical/shift.rs
vendored
Normal file
46
vendor/serde_json/src/lexical/shift.rs
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Bit-shift helpers.
|
||||
|
||||
use super::float::ExtendedFloat;
|
||||
use core::mem;
|
||||
|
||||
// Shift extended-precision float right `shift` bytes.
|
||||
#[inline]
|
||||
pub(crate) fn shr(fp: &mut ExtendedFloat, shift: i32) {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!((shift as u64) < bits, "shr() overflow in shift right.");
|
||||
|
||||
fp.mant >>= shift;
|
||||
fp.exp += shift;
|
||||
}
|
||||
|
||||
// Shift extended-precision float right `shift` bytes.
|
||||
//
|
||||
// Accepts when the shift is the same as the type size, and
|
||||
// sets the value to 0.
|
||||
#[inline]
|
||||
pub(crate) fn overflowing_shr(fp: &mut ExtendedFloat, shift: i32) {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!(
|
||||
(shift as u64) <= bits,
|
||||
"overflowing_shr() overflow in shift right."
|
||||
);
|
||||
|
||||
fp.mant = if shift as u64 == bits {
|
||||
0
|
||||
} else {
|
||||
fp.mant >> shift
|
||||
};
|
||||
fp.exp += shift;
|
||||
}
|
||||
|
||||
// Shift extended-precision float left `shift` bytes.
|
||||
#[inline]
|
||||
pub(crate) fn shl(fp: &mut ExtendedFloat, shift: i32) {
|
||||
let bits: u64 = mem::size_of::<u64>() as u64 * 8;
|
||||
debug_assert!((shift as u64) < bits, "shl() overflow in shift left.");
|
||||
|
||||
fp.mant <<= shift;
|
||||
fp.exp -= shift;
|
||||
}
|
70
vendor/serde_json/src/lexical/small_powers.rs
vendored
Normal file
70
vendor/serde_json/src/lexical/small_powers.rs
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
//! Pre-computed small powers.
|
||||
|
||||
// 32 BIT
|
||||
#[cfg(limb_width_32)]
|
||||
pub(crate) const POW5_32: [u32; 14] = [
|
||||
1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625,
|
||||
1220703125,
|
||||
];
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
pub(crate) const POW10_32: [u32; 10] = [
|
||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
|
||||
];
|
||||
|
||||
// 64 BIT
|
||||
#[cfg(limb_width_64)]
|
||||
pub(crate) const POW5_64: [u64; 28] = [
|
||||
1,
|
||||
5,
|
||||
25,
|
||||
125,
|
||||
625,
|
||||
3125,
|
||||
15625,
|
||||
78125,
|
||||
390625,
|
||||
1953125,
|
||||
9765625,
|
||||
48828125,
|
||||
244140625,
|
||||
1220703125,
|
||||
6103515625,
|
||||
30517578125,
|
||||
152587890625,
|
||||
762939453125,
|
||||
3814697265625,
|
||||
19073486328125,
|
||||
95367431640625,
|
||||
476837158203125,
|
||||
2384185791015625,
|
||||
11920928955078125,
|
||||
59604644775390625,
|
||||
298023223876953125,
|
||||
1490116119384765625,
|
||||
7450580596923828125,
|
||||
];
|
||||
pub(crate) const POW10_64: [u64; 20] = [
|
||||
1,
|
||||
10,
|
||||
100,
|
||||
1000,
|
||||
10000,
|
||||
100000,
|
||||
1000000,
|
||||
10000000,
|
||||
100000000,
|
||||
1000000000,
|
||||
10000000000,
|
||||
100000000000,
|
||||
1000000000000,
|
||||
10000000000000,
|
||||
100000000000000,
|
||||
1000000000000000,
|
||||
10000000000000000,
|
||||
100000000000000000,
|
||||
1000000000000000000,
|
||||
10000000000000000000,
|
||||
];
|
419
vendor/serde_json/src/lib.rs
vendored
Normal file
419
vendor/serde_json/src/lib.rs
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
//! # Serde JSON
|
||||
//!
|
||||
//! JSON is a ubiquitous open-standard format that uses human-readable text to
|
||||
//! transmit data objects consisting of key-value pairs.
|
||||
//!
|
||||
//! ```json
|
||||
//! {
|
||||
//! "name": "John Doe",
|
||||
//! "age": 43,
|
||||
//! "address": {
|
||||
//! "street": "10 Downing Street",
|
||||
//! "city": "London"
|
||||
//! },
|
||||
//! "phones": [
|
||||
//! "+44 1234567",
|
||||
//! "+44 2345678"
|
||||
//! ]
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! There are three common ways that you might find yourself needing to work
|
||||
//! with JSON data in Rust.
|
||||
//!
|
||||
//! - **As text data.** An unprocessed string of JSON data that you receive on
|
||||
//! an HTTP endpoint, read from a file, or prepare to send to a remote
|
||||
//! server.
|
||||
//! - **As an untyped or loosely typed representation.** Maybe you want to
|
||||
//! check that some JSON data is valid before passing it on, but without
|
||||
//! knowing the structure of what it contains. Or you want to do very basic
|
||||
//! manipulations like insert a key in a particular spot.
|
||||
//! - **As a strongly typed Rust data structure.** When you expect all or most
|
||||
//! of your data to conform to a particular structure and want to get real
|
||||
//! work done without JSON's loosey-goosey nature tripping you up.
|
||||
//!
|
||||
//! Serde JSON provides efficient, flexible, safe ways of converting data
|
||||
//! between each of these representations.
|
||||
//!
|
||||
//! # Operating on untyped JSON values
|
||||
//!
|
||||
//! Any valid JSON data can be manipulated in the following recursive enum
|
||||
//! representation. This data structure is [`serde_json::Value`][value].
|
||||
//!
|
||||
//! ```
|
||||
//! # use serde_json::{Number, Map};
|
||||
//! #
|
||||
//! # #[allow(dead_code)]
|
||||
//! enum Value {
|
||||
//! Null,
|
||||
//! Bool(bool),
|
||||
//! Number(Number),
|
||||
//! String(String),
|
||||
//! Array(Vec<Value>),
|
||||
//! Object(Map<String, Value>),
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! A string of JSON data can be parsed into a `serde_json::Value` by the
|
||||
//! [`serde_json::from_str`][from_str] function. There is also [`from_slice`]
|
||||
//! for parsing from a byte slice &\[u8\] and [`from_reader`] for parsing from
|
||||
//! any `io::Read` like a File or a TCP stream.
|
||||
//!
|
||||
//! ```
|
||||
//! use serde_json::{Result, Value};
|
||||
//!
|
||||
//! fn untyped_example() -> Result<()> {
|
||||
//! // Some JSON input data as a &str. Maybe this comes from the user.
|
||||
//! let data = r#"
|
||||
//! {
|
||||
//! "name": "John Doe",
|
||||
//! "age": 43,
|
||||
//! "phones": [
|
||||
//! "+44 1234567",
|
||||
//! "+44 2345678"
|
||||
//! ]
|
||||
//! }"#;
|
||||
//!
|
||||
//! // Parse the string of data into serde_json::Value.
|
||||
//! let v: Value = serde_json::from_str(data)?;
|
||||
//!
|
||||
//! // Access parts of the data by indexing with square brackets.
|
||||
//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! #
|
||||
//! # fn main() {
|
||||
//! # untyped_example().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! The result of square bracket indexing like `v["name"]` is a borrow of the
|
||||
//! data at that index, so the type is `&Value`. A JSON map can be indexed with
|
||||
//! string keys, while a JSON array can be indexed with integer keys. If the
|
||||
//! type of the data is not right for the type with which it is being indexed,
|
||||
//! or if a map does not contain the key being indexed, or if the index into a
|
||||
//! vector is out of bounds, the returned element is `Value::Null`.
|
||||
//!
|
||||
//! When a `Value` is printed, it is printed as a JSON string. So in the code
|
||||
//! above, the output looks like `Please call "John Doe" at the number "+44
|
||||
//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value`
|
||||
//! containing a JSON string and its JSON representation is `"John Doe"`.
|
||||
//! Printing as a plain string without quotation marks involves converting from
|
||||
//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of
|
||||
//! `Value` as described in the following section.
|
||||
//!
|
||||
//! [`as_str()`]: crate::Value::as_str
|
||||
//!
|
||||
//! The `Value` representation is sufficient for very basic tasks but can be
|
||||
//! tedious to work with for anything more significant. Error handling is
|
||||
//! verbose to implement correctly, for example imagine trying to detect the
|
||||
//! presence of unrecognized fields in the input data. The compiler is powerless
|
||||
//! to help you when you make a mistake, for example imagine typoing `v["name"]`
|
||||
//! as `v["nmae"]` in one of the dozens of places it is used in your code.
|
||||
//!
|
||||
//! # Parsing JSON as strongly typed data structures
|
||||
//!
|
||||
//! Serde provides a powerful way of mapping JSON data into Rust data structures
|
||||
//! largely automatically.
|
||||
//!
|
||||
//! ```
|
||||
//! use serde::{Deserialize, Serialize};
|
||||
//! use serde_json::Result;
|
||||
//!
|
||||
//! #[derive(Serialize, Deserialize)]
|
||||
//! struct Person {
|
||||
//! name: String,
|
||||
//! age: u8,
|
||||
//! phones: Vec<String>,
|
||||
//! }
|
||||
//!
|
||||
//! fn typed_example() -> Result<()> {
|
||||
//! // Some JSON input data as a &str. Maybe this comes from the user.
|
||||
//! let data = r#"
|
||||
//! {
|
||||
//! "name": "John Doe",
|
||||
//! "age": 43,
|
||||
//! "phones": [
|
||||
//! "+44 1234567",
|
||||
//! "+44 2345678"
|
||||
//! ]
|
||||
//! }"#;
|
||||
//!
|
||||
//! // Parse the string of data into a Person object. This is exactly the
|
||||
//! // same function as the one that produced serde_json::Value above, but
|
||||
//! // now we are asking it for a Person as output.
|
||||
//! let p: Person = serde_json::from_str(data)?;
|
||||
//!
|
||||
//! // Do things just like with any other Rust data structure.
|
||||
//! println!("Please call {} at the number {}", p.name, p.phones[0]);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! #
|
||||
//! # fn main() {
|
||||
//! # typed_example().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! This is the same `serde_json::from_str` function as before, but this time we
|
||||
//! assign the return value to a variable of type `Person` so Serde will
|
||||
//! automatically interpret the input data as a `Person` and produce informative
|
||||
//! error messages if the layout does not conform to what a `Person` is expected
|
||||
//! to look like.
|
||||
//!
|
||||
//! Any type that implements Serde's `Deserialize` trait can be deserialized
|
||||
//! this way. This includes built-in Rust standard library types like `Vec<T>`
|
||||
//! and `HashMap<K, V>`, as well as any structs or enums annotated with
|
||||
//! `#[derive(Deserialize)]`.
|
||||
//!
|
||||
//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
|
||||
//! use it correctly like they do for any other Rust code. The IDE can
|
||||
//! autocomplete field names to prevent typos, which was impossible in the
|
||||
//! `serde_json::Value` representation. And the Rust compiler can check that
|
||||
//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
|
||||
//! `Vec<String>` so indexing into it makes sense and produces a `String`.
|
||||
//!
|
||||
//! # Constructing JSON values
|
||||
//!
|
||||
//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
|
||||
//! objects with very natural JSON syntax.
|
||||
//!
|
||||
//! ```
|
||||
//! use serde_json::json;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // The type of `john` is `serde_json::Value`
|
||||
//! let john = json!({
|
||||
//! "name": "John Doe",
|
||||
//! "age": 43,
|
||||
//! "phones": [
|
||||
//! "+44 1234567",
|
||||
//! "+44 2345678"
|
||||
//! ]
|
||||
//! });
|
||||
//!
|
||||
//! println!("first phone number: {}", john["phones"][0]);
|
||||
//!
|
||||
//! // Convert to a string of JSON and print it out
|
||||
//! println!("{}", john.to_string());
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! The `Value::to_string()` function converts a `serde_json::Value` into a
|
||||
//! `String` of JSON text.
|
||||
//!
|
||||
//! One neat thing about the `json!` macro is that variables and expressions can
|
||||
//! be interpolated directly into the JSON value as you are building it. Serde
|
||||
//! will check at compile time that the value you are interpolating is able to
|
||||
//! be represented as JSON.
|
||||
//!
|
||||
//! ```
|
||||
//! # use serde_json::json;
|
||||
//! #
|
||||
//! # fn random_phone() -> u16 { 0 }
|
||||
//! #
|
||||
//! let full_name = "John Doe";
|
||||
//! let age_last_year = 42;
|
||||
//!
|
||||
//! // The type of `john` is `serde_json::Value`
|
||||
//! let john = json!({
|
||||
//! "name": full_name,
|
||||
//! "age": age_last_year + 1,
|
||||
//! "phones": [
|
||||
//! format!("+44 {}", random_phone())
|
||||
//! ]
|
||||
//! });
|
||||
//! ```
|
||||
//!
|
||||
//! This is amazingly convenient, but we have the problem we had before with
|
||||
//! `Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde
|
||||
//! JSON provides a better way of serializing strongly-typed data structures
|
||||
//! into JSON text.
|
||||
//!
|
||||
//! # Creating JSON by serializing data structures
|
||||
//!
|
||||
//! A data structure can be converted to a JSON string by
|
||||
//! [`serde_json::to_string`][to_string]. There is also
|
||||
//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
|
||||
//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
|
||||
//! such as a File or a TCP stream.
|
||||
//!
|
||||
//! ```
|
||||
//! use serde::{Deserialize, Serialize};
|
||||
//! use serde_json::Result;
|
||||
//!
|
||||
//! #[derive(Serialize, Deserialize)]
|
||||
//! struct Address {
|
||||
//! street: String,
|
||||
//! city: String,
|
||||
//! }
|
||||
//!
|
||||
//! fn print_an_address() -> Result<()> {
|
||||
//! // Some data structure.
|
||||
//! let address = Address {
|
||||
//! street: "10 Downing Street".to_owned(),
|
||||
//! city: "London".to_owned(),
|
||||
//! };
|
||||
//!
|
||||
//! // Serialize it to a JSON string.
|
||||
//! let j = serde_json::to_string(&address)?;
|
||||
//!
|
||||
//! // Print, write to a file, or send to an HTTP server.
|
||||
//! println!("{}", j);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! #
|
||||
//! # fn main() {
|
||||
//! # print_an_address().unwrap();
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Any type that implements Serde's `Serialize` trait can be serialized this
|
||||
//! way. This includes built-in Rust standard library types like `Vec<T>` and
|
||||
//! `HashMap<K, V>`, as well as any structs or enums annotated with
|
||||
//! `#[derive(Serialize)]`.
|
||||
//!
|
||||
//! # No-std support
|
||||
//!
|
||||
//! As long as there is a memory allocator, it is possible to use serde_json
|
||||
//! without the rest of the Rust standard library. Disable the default "std"
|
||||
//! feature and enable the "alloc" feature:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||
//! ```
|
||||
//!
|
||||
//! For JSON support in Serde without a memory allocator, please see the
|
||||
//! [`serde-json-core`] crate.
|
||||
//!
|
||||
//! [value]: crate::value::Value
|
||||
//! [from_str]: crate::de::from_str
|
||||
//! [from_slice]: crate::de::from_slice
|
||||
//! [from_reader]: crate::de::from_reader
|
||||
//! [to_string]: crate::ser::to_string
|
||||
//! [to_vec]: crate::ser::to_vec
|
||||
//! [to_writer]: crate::ser::to_writer
|
||||
//! [macro]: crate::json
|
||||
//! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_json/1.0.111")]
|
||||
// Ignored clippy lints
|
||||
#![allow(
|
||||
clippy::collapsible_else_if,
|
||||
clippy::comparison_chain,
|
||||
clippy::deprecated_cfg_attr,
|
||||
clippy::doc_markdown,
|
||||
clippy::excessive_precision,
|
||||
clippy::explicit_auto_deref,
|
||||
clippy::float_cmp,
|
||||
clippy::manual_range_contains,
|
||||
clippy::match_like_matches_macro,
|
||||
clippy::match_single_binding,
|
||||
clippy::needless_doctest_main,
|
||||
clippy::needless_late_init,
|
||||
clippy::return_self_not_must_use,
|
||||
clippy::transmute_ptr_to_ptr,
|
||||
clippy::unnecessary_wraps
|
||||
)]
|
||||
// Ignored clippy_pedantic lints
|
||||
#![allow(
|
||||
// Deserializer::from_str, into_iter
|
||||
clippy::should_implement_trait,
|
||||
// integer and float ser/de requires these sorts of casts
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_sign_loss,
|
||||
// correctly used
|
||||
clippy::enum_glob_use,
|
||||
clippy::if_not_else,
|
||||
clippy::integer_division,
|
||||
clippy::let_underscore_untyped,
|
||||
clippy::map_err_ignore,
|
||||
clippy::match_same_arms,
|
||||
clippy::similar_names,
|
||||
clippy::unused_self,
|
||||
clippy::wildcard_imports,
|
||||
// things are often more readable this way
|
||||
clippy::cast_lossless,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::redundant_else,
|
||||
clippy::shadow_unrelated,
|
||||
clippy::single_match_else,
|
||||
clippy::too_many_lines,
|
||||
clippy::unreadable_literal,
|
||||
clippy::unseparated_literal_suffix,
|
||||
clippy::use_self,
|
||||
clippy::zero_prefixed_literal,
|
||||
// we support older compilers
|
||||
clippy::checked_conversions,
|
||||
clippy::mem_replace_with_default,
|
||||
// noisy
|
||||
clippy::missing_errors_doc,
|
||||
clippy::must_use_candidate,
|
||||
)]
|
||||
// Restrictions
|
||||
#![deny(clippy::question_mark_used)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
#[doc(inline)]
|
||||
pub use crate::de::from_reader;
|
||||
#[doc(inline)]
|
||||
pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer};
|
||||
#[doc(inline)]
|
||||
pub use crate::error::{Error, Result};
|
||||
#[doc(inline)]
|
||||
pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty};
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
#[doc(inline)]
|
||||
pub use crate::ser::{to_writer, to_writer_pretty, Serializer};
|
||||
#[doc(inline)]
|
||||
pub use crate::value::{from_value, to_value, Map, Number, Value};
|
||||
|
||||
// We only use our own error type; no need for From conversions provided by the
|
||||
// standard library's try! macro. This reduces lines of LLVM IR by 4%.
|
||||
macro_rules! tri {
|
||||
($e:expr $(,)?) => {
|
||||
match $e {
|
||||
core::result::Result::Ok(val) => val,
|
||||
core::result::Result::Err(err) => return core::result::Result::Err(err),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
pub mod de;
|
||||
pub mod error;
|
||||
pub mod map;
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||
pub mod ser;
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod ser;
|
||||
pub mod value;
|
||||
|
||||
mod features_check;
|
||||
|
||||
mod io;
|
||||
#[cfg(feature = "std")]
|
||||
mod iter;
|
||||
#[cfg(feature = "float_roundtrip")]
|
||||
mod lexical;
|
||||
mod number;
|
||||
mod read;
|
||||
|
||||
#[cfg(feature = "raw_value")]
|
||||
mod raw;
|
304
vendor/serde_json/src/macros.rs
vendored
Normal file
304
vendor/serde_json/src/macros.rs
vendored
Normal file
@ -0,0 +1,304 @@
|
||||
/// Construct a `serde_json::Value` from a JSON literal.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let value = json!({
|
||||
/// "code": 200,
|
||||
/// "success": true,
|
||||
/// "payload": {
|
||||
/// "features": [
|
||||
/// "serde",
|
||||
/// "json"
|
||||
/// ],
|
||||
/// "homepage": null
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// Variables or expressions can be interpolated into the JSON literal. Any type
|
||||
/// interpolated into an array element or object value must implement Serde's
|
||||
/// `Serialize` trait, while any type interpolated into a object key must
|
||||
/// implement `Into<String>`. If the `Serialize` implementation of the
|
||||
/// interpolated type decides to fail, or if the interpolated type contains a
|
||||
/// map with non-string keys, the `json!` macro will panic.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let code = 200;
|
||||
/// let features = vec!["serde", "json"];
|
||||
///
|
||||
/// let value = json!({
|
||||
/// "code": code,
|
||||
/// "success": code == 200,
|
||||
/// "payload": {
|
||||
/// features[0]: features[1]
|
||||
/// }
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// Trailing commas are allowed inside both arrays and objects.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let value = json!([
|
||||
/// "notice",
|
||||
/// "the",
|
||||
/// "trailing",
|
||||
/// "comma -->",
|
||||
/// ]);
|
||||
/// ```
|
||||
#[macro_export(local_inner_macros)]
|
||||
macro_rules! json {
|
||||
// Hide distracting implementation details from the generated rustdoc.
|
||||
($($json:tt)+) => {
|
||||
json_internal!($($json)+)
|
||||
};
|
||||
}
|
||||
|
||||
// Rocket relies on this because they export their own `json!` with a different
|
||||
// doc comment than ours, and various Rust bugs prevent them from calling our
|
||||
// `json!` from their `json!` so they call `json_internal!` directly. Check with
|
||||
// @SergioBenitez before making breaking changes to this macro.
|
||||
//
|
||||
// Changes are fine as long as `json_internal!` does not call any new helper
|
||||
// macros and can still be invoked as `json_internal!($($json)+)`.
|
||||
#[macro_export(local_inner_macros)]
|
||||
#[doc(hidden)]
|
||||
macro_rules! json_internal {
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TT muncher for parsing the inside of an array [...]. Produces a vec![...]
|
||||
// of the elements.
|
||||
//
|
||||
// Must be invoked as: json_internal!(@array [] $($tt)*)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Done with trailing comma.
|
||||
(@array [$($elems:expr,)*]) => {
|
||||
json_internal_vec![$($elems,)*]
|
||||
};
|
||||
|
||||
// Done without trailing comma.
|
||||
(@array [$($elems:expr),*]) => {
|
||||
json_internal_vec![$($elems),*]
|
||||
};
|
||||
|
||||
// Next element is `null`.
|
||||
(@array [$($elems:expr,)*] null $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*)
|
||||
};
|
||||
|
||||
// Next element is `true`.
|
||||
(@array [$($elems:expr,)*] true $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*)
|
||||
};
|
||||
|
||||
// Next element is `false`.
|
||||
(@array [$($elems:expr,)*] false $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*)
|
||||
};
|
||||
|
||||
// Next element is an array.
|
||||
(@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*)
|
||||
};
|
||||
|
||||
// Next element is a map.
|
||||
(@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*)
|
||||
};
|
||||
|
||||
// Next element is an expression followed by comma.
|
||||
(@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*)
|
||||
};
|
||||
|
||||
// Last element is an expression with no trailing comma.
|
||||
(@array [$($elems:expr,)*] $last:expr) => {
|
||||
json_internal!(@array [$($elems,)* json_internal!($last)])
|
||||
};
|
||||
|
||||
// Comma after the most recent element.
|
||||
(@array [$($elems:expr),*] , $($rest:tt)*) => {
|
||||
json_internal!(@array [$($elems,)*] $($rest)*)
|
||||
};
|
||||
|
||||
// Unexpected token after most recent element.
|
||||
(@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
|
||||
json_unexpected!($unexpected)
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// TT muncher for parsing the inside of an object {...}. Each entry is
|
||||
// inserted into the given map variable.
|
||||
//
|
||||
// Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*))
|
||||
//
|
||||
// We require two copies of the input tokens so that we can match on one
|
||||
// copy and trigger errors on the other copy.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Done.
|
||||
(@object $object:ident () () ()) => {};
|
||||
|
||||
// Insert the current entry followed by trailing comma.
|
||||
(@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
|
||||
let _ = $object.insert(($($key)+).into(), $value);
|
||||
json_internal!(@object $object () ($($rest)*) ($($rest)*));
|
||||
};
|
||||
|
||||
// Current entry followed by unexpected token.
|
||||
(@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
|
||||
json_unexpected!($unexpected);
|
||||
};
|
||||
|
||||
// Insert the last entry without trailing comma.
|
||||
(@object $object:ident [$($key:tt)+] ($value:expr)) => {
|
||||
let _ = $object.insert(($($key)+).into(), $value);
|
||||
};
|
||||
|
||||
// Next value is `null`.
|
||||
(@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*);
|
||||
};
|
||||
|
||||
// Next value is `true`.
|
||||
(@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*);
|
||||
};
|
||||
|
||||
// Next value is `false`.
|
||||
(@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*);
|
||||
};
|
||||
|
||||
// Next value is an array.
|
||||
(@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*);
|
||||
};
|
||||
|
||||
// Next value is a map.
|
||||
(@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*);
|
||||
};
|
||||
|
||||
// Next value is an expression followed by comma.
|
||||
(@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*);
|
||||
};
|
||||
|
||||
// Last value is an expression with no trailing comma.
|
||||
(@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
|
||||
json_internal!(@object $object [$($key)+] (json_internal!($value)));
|
||||
};
|
||||
|
||||
// Missing value for last entry. Trigger a reasonable error message.
|
||||
(@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
|
||||
// "unexpected end of macro invocation"
|
||||
json_internal!();
|
||||
};
|
||||
|
||||
// Missing colon and value for last entry. Trigger a reasonable error
|
||||
// message.
|
||||
(@object $object:ident ($($key:tt)+) () $copy:tt) => {
|
||||
// "unexpected end of macro invocation"
|
||||
json_internal!();
|
||||
};
|
||||
|
||||
// Misplaced colon. Trigger a reasonable error message.
|
||||
(@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
|
||||
// Takes no arguments so "no rules expected the token `:`".
|
||||
json_unexpected!($colon);
|
||||
};
|
||||
|
||||
// Found a comma inside a key. Trigger a reasonable error message.
|
||||
(@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
|
||||
// Takes no arguments so "no rules expected the token `,`".
|
||||
json_unexpected!($comma);
|
||||
};
|
||||
|
||||
// Key is fully parenthesized. This avoids clippy double_parens false
|
||||
// positives because the parenthesization may be necessary here.
|
||||
(@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*));
|
||||
};
|
||||
|
||||
// Refuse to absorb colon token into key expression.
|
||||
(@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
|
||||
json_expect_expr_comma!($($unexpected)+);
|
||||
};
|
||||
|
||||
// Munch a token into the current key.
|
||||
(@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
|
||||
json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// The main implementation.
|
||||
//
|
||||
// Must be invoked as: json_internal!($($json)+)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(null) => {
|
||||
$crate::Value::Null
|
||||
};
|
||||
|
||||
(true) => {
|
||||
$crate::Value::Bool(true)
|
||||
};
|
||||
|
||||
(false) => {
|
||||
$crate::Value::Bool(false)
|
||||
};
|
||||
|
||||
([]) => {
|
||||
$crate::Value::Array(json_internal_vec![])
|
||||
};
|
||||
|
||||
([ $($tt:tt)+ ]) => {
|
||||
$crate::Value::Array(json_internal!(@array [] $($tt)+))
|
||||
};
|
||||
|
||||
({}) => {
|
||||
$crate::Value::Object($crate::Map::new())
|
||||
};
|
||||
|
||||
({ $($tt:tt)+ }) => {
|
||||
$crate::Value::Object({
|
||||
let mut object = $crate::Map::new();
|
||||
json_internal!(@object object () ($($tt)+) ($($tt)+));
|
||||
object
|
||||
})
|
||||
};
|
||||
|
||||
// Any Serialize type: numbers, strings, struct literals, variables etc.
|
||||
// Must be below every other rule.
|
||||
($other:expr) => {
|
||||
$crate::to_value(&$other).unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
// The json_internal macro above cannot invoke vec directly because it uses
|
||||
// local_inner_macros. A vec invocation there would resolve to $crate::vec.
|
||||
// Instead invoke vec here outside of local_inner_macros.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! json_internal_vec {
|
||||
($($content:tt)*) => {
|
||||
vec![$($content)*]
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! json_unexpected {
|
||||
() => {};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! json_expect_expr_comma {
|
||||
($e:expr , $($tt:tt)*) => {};
|
||||
}
|
901
vendor/serde_json/src/map.rs
vendored
Normal file
901
vendor/serde_json/src/map.rs
vendored
Normal file
@ -0,0 +1,901 @@
|
||||
//! A map of String to serde_json::Value.
|
||||
//!
|
||||
//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order`
|
||||
//! feature of serde_json to use [`IndexMap`] instead.
|
||||
//!
|
||||
//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
|
||||
//! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html
|
||||
|
||||
use crate::value::Value;
|
||||
use alloc::string::String;
|
||||
use core::borrow::Borrow;
|
||||
use core::fmt::{self, Debug};
|
||||
use core::hash::Hash;
|
||||
use core::iter::FusedIterator;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
use core::mem;
|
||||
use core::ops;
|
||||
use serde::de;
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
use alloc::collections::{btree_map, BTreeMap};
|
||||
#[cfg(feature = "preserve_order")]
|
||||
use indexmap::{self, IndexMap};
|
||||
|
||||
/// Represents a JSON key/value type.
|
||||
pub struct Map<K, V> {
|
||||
map: MapImpl<K, V>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type MapImpl<K, V> = BTreeMap<K, V>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type MapImpl<K, V> = IndexMap<K, V>;
|
||||
|
||||
impl Map<String, Value> {
|
||||
/// Makes a new empty Map.
|
||||
#[inline]
|
||||
pub fn new() -> Self {
|
||||
Map {
|
||||
map: MapImpl::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Makes a new empty Map with the given initial capacity.
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Map {
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
map: {
|
||||
// does not support with_capacity
|
||||
let _ = capacity;
|
||||
BTreeMap::new()
|
||||
},
|
||||
#[cfg(feature = "preserve_order")]
|
||||
map: IndexMap::with_capacity(capacity),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the map, removing all values.
|
||||
#[inline]
|
||||
pub fn clear(&mut self) {
|
||||
self.map.clear();
|
||||
}
|
||||
|
||||
/// Returns a reference to the value corresponding to the key.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
#[inline]
|
||||
pub fn get<Q>(&self, key: &Q) -> Option<&Value>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
self.map.get(key)
|
||||
}
|
||||
|
||||
/// Returns true if the map contains a value for the specified key.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
#[inline]
|
||||
pub fn contains_key<Q>(&self, key: &Q) -> bool
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
self.map.contains_key(key)
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the value corresponding to the key.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
#[inline]
|
||||
pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut Value>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
self.map.get_mut(key)
|
||||
}
|
||||
|
||||
/// Returns the key-value pair matching the given key.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
#[inline]
|
||||
pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&String, &Value)>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
self.map.get_key_value(key)
|
||||
}
|
||||
|
||||
/// Inserts a key-value pair into the map.
|
||||
///
|
||||
/// If the map did not have this key present, `None` is returned.
|
||||
///
|
||||
/// If the map did have this key present, the value is updated, and the old
|
||||
/// value is returned.
|
||||
#[inline]
|
||||
pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
|
||||
self.map.insert(k, v)
|
||||
}
|
||||
|
||||
/// Removes a key from the map, returning the value at the key if the key
|
||||
/// was previously in the map.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
#[inline]
|
||||
pub fn remove<Q>(&mut self, key: &Q) -> Option<Value>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
#[cfg(feature = "preserve_order")]
|
||||
return self.map.swap_remove(key);
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
return self.map.remove(key);
|
||||
}
|
||||
|
||||
/// Removes a key from the map, returning the stored key and value if the
|
||||
/// key was previously in the map.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering
|
||||
/// on the borrowed form *must* match the ordering on the key type.
|
||||
pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(String, Value)>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
self.map.remove_entry(key)
|
||||
}
|
||||
|
||||
/// Moves all elements from other into self, leaving other empty.
|
||||
#[inline]
|
||||
pub fn append(&mut self, other: &mut Self) {
|
||||
#[cfg(feature = "preserve_order")]
|
||||
self.map
|
||||
.extend(mem::replace(&mut other.map, MapImpl::default()));
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
self.map.append(&mut other.map);
|
||||
}
|
||||
|
||||
/// Gets the given key's corresponding entry in the map for in-place
|
||||
/// manipulation.
|
||||
pub fn entry<S>(&mut self, key: S) -> Entry
|
||||
where
|
||||
S: Into<String>,
|
||||
{
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
use alloc::collections::btree_map::Entry as EntryImpl;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
use indexmap::map::Entry as EntryImpl;
|
||||
|
||||
match self.map.entry(key.into()) {
|
||||
EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
|
||||
EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of elements in the map.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
/// Returns true if the map contains no elements.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty()
|
||||
}
|
||||
|
||||
/// Gets an iterator over the entries of the map.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> Iter {
|
||||
Iter {
|
||||
iter: self.map.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a mutable iterator over the entries of the map.
|
||||
#[inline]
|
||||
pub fn iter_mut(&mut self) -> IterMut {
|
||||
IterMut {
|
||||
iter: self.map.iter_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets an iterator over the keys of the map.
|
||||
#[inline]
|
||||
pub fn keys(&self) -> Keys {
|
||||
Keys {
|
||||
iter: self.map.keys(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets an iterator over the values of the map.
|
||||
#[inline]
|
||||
pub fn values(&self) -> Values {
|
||||
Values {
|
||||
iter: self.map.values(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets an iterator over mutable values of the map.
|
||||
#[inline]
|
||||
pub fn values_mut(&mut self) -> ValuesMut {
|
||||
ValuesMut {
|
||||
iter: self.map.values_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Retains only the elements specified by the predicate.
|
||||
///
|
||||
/// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)`
|
||||
/// returns `false`.
|
||||
#[inline]
|
||||
pub fn retain<F>(&mut self, f: F)
|
||||
where
|
||||
F: FnMut(&String, &mut Value) -> bool,
|
||||
{
|
||||
self.map.retain(f);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7655
|
||||
impl Default for Map<String, Value> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Map {
|
||||
map: MapImpl::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Map<String, Value> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Map {
|
||||
map: self.map.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clone_from(&mut self, source: &Self) {
|
||||
self.map.clone_from(&source.map);
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Map<String, Value> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.map.eq(&other.map)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Map<String, Value> {}
|
||||
|
||||
/// Access an element of this map. Panics if the given key is not present in the
|
||||
/// map.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::Value;
|
||||
/// #
|
||||
/// # let val = &Value::String("".to_owned());
|
||||
/// # let _ =
|
||||
/// match val {
|
||||
/// Value::String(s) => Some(s.as_str()),
|
||||
/// Value::Array(arr) => arr[0].as_str(),
|
||||
/// Value::Object(map) => map["type"].as_str(),
|
||||
/// _ => None,
|
||||
/// }
|
||||
/// # ;
|
||||
/// ```
|
||||
impl<'a, Q> ops::Index<&'a Q> for Map<String, Value>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
type Output = Value;
|
||||
|
||||
fn index(&self, index: &Q) -> &Value {
|
||||
self.map.index(index)
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutably access an element of this map. Panics if the given key is not
|
||||
/// present in the map.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// # let mut map = serde_json::Map::new();
|
||||
/// # map.insert("key".to_owned(), serde_json::Value::Null);
|
||||
/// #
|
||||
/// map["key"] = json!("value");
|
||||
/// ```
|
||||
impl<'a, Q> ops::IndexMut<&'a Q> for Map<String, Value>
|
||||
where
|
||||
String: Borrow<Q>,
|
||||
Q: ?Sized + Ord + Eq + Hash,
|
||||
{
|
||||
fn index_mut(&mut self, index: &Q) -> &mut Value {
|
||||
self.map.get_mut(index).expect("no entry found for key")
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Map<String, Value> {
|
||||
#[inline]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
self.map.fmt(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl serde::ser::Serialize for Map<String, Value> {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::ser::Serializer,
|
||||
{
|
||||
use serde::ser::SerializeMap;
|
||||
let mut map = tri!(serializer.serialize_map(Some(self.len())));
|
||||
for (k, v) in self {
|
||||
tri!(map.serialize_entry(k, v));
|
||||
}
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> de::Deserialize<'de> for Map<String, Value> {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
struct Visitor;
|
||||
|
||||
impl<'de> de::Visitor<'de> for Visitor {
|
||||
type Value = Map<String, Value>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a map")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(Map::new())
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
#[inline]
|
||||
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
||||
where
|
||||
V: de::MapAccess<'de>,
|
||||
{
|
||||
let mut values = Map::new();
|
||||
|
||||
while let Some((key, value)) = tri!(visitor.next_entry()) {
|
||||
values.insert(key, value);
|
||||
}
|
||||
|
||||
Ok(values)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_map(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<(String, Value)> for Map<String, Value> {
|
||||
fn from_iter<T>(iter: T) -> Self
|
||||
where
|
||||
T: IntoIterator<Item = (String, Value)>,
|
||||
{
|
||||
Map {
|
||||
map: FromIterator::from_iter(iter),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<(String, Value)> for Map<String, Value> {
|
||||
fn extend<T>(&mut self, iter: T)
|
||||
where
|
||||
T: IntoIterator<Item = (String, Value)>,
|
||||
{
|
||||
self.map.extend(iter);
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! delegate_iterator {
|
||||
(($name:ident $($generics:tt)*) => $item:ty) => {
|
||||
impl $($generics)* Iterator for $name $($generics)* {
|
||||
type Item = $item;
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next()
|
||||
}
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl $($generics)* DoubleEndedIterator for $name $($generics)* {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
impl $($generics)* ExactSizeIterator for $name $($generics)* {
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.iter.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl $($generics)* FusedIterator for $name $($generics)* {}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A view into a single entry in a map, which may either be vacant or occupied.
|
||||
/// This enum is constructed from the [`entry`] method on [`Map`].
|
||||
///
|
||||
/// [`entry`]: struct.Map.html#method.entry
|
||||
/// [`Map`]: struct.Map.html
|
||||
pub enum Entry<'a> {
|
||||
/// A vacant Entry.
|
||||
Vacant(VacantEntry<'a>),
|
||||
/// An occupied Entry.
|
||||
Occupied(OccupiedEntry<'a>),
|
||||
}
|
||||
|
||||
/// A vacant Entry. It is part of the [`Entry`] enum.
|
||||
///
|
||||
/// [`Entry`]: enum.Entry.html
|
||||
pub struct VacantEntry<'a> {
|
||||
vacant: VacantEntryImpl<'a>,
|
||||
}
|
||||
|
||||
/// An occupied Entry. It is part of the [`Entry`] enum.
|
||||
///
|
||||
/// [`Entry`]: enum.Entry.html
|
||||
pub struct OccupiedEntry<'a> {
|
||||
occupied: OccupiedEntryImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>;
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>;
|
||||
|
||||
impl<'a> Entry<'a> {
|
||||
/// Returns a reference to this entry's key.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// assert_eq!(map.entry("serde").key(), &"serde");
|
||||
/// ```
|
||||
pub fn key(&self) -> &String {
|
||||
match self {
|
||||
Entry::Vacant(e) => e.key(),
|
||||
Entry::Occupied(e) => e.key(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures a value is in the entry by inserting the default if empty, and
|
||||
/// returns a mutable reference to the value in the entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.entry("serde").or_insert(json!(12));
|
||||
///
|
||||
/// assert_eq!(map["serde"], 12);
|
||||
/// ```
|
||||
pub fn or_insert(self, default: Value) -> &'a mut Value {
|
||||
match self {
|
||||
Entry::Vacant(entry) => entry.insert(default),
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures a value is in the entry by inserting the result of the default
|
||||
/// function if empty, and returns a mutable reference to the value in the
|
||||
/// entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.entry("serde").or_insert_with(|| json!("hoho"));
|
||||
///
|
||||
/// assert_eq!(map["serde"], "hoho".to_owned());
|
||||
/// ```
|
||||
pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
|
||||
where
|
||||
F: FnOnce() -> Value,
|
||||
{
|
||||
match self {
|
||||
Entry::Vacant(entry) => entry.insert(default()),
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides in-place mutable access to an occupied entry before any
|
||||
/// potential inserts into the map.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.entry("serde")
|
||||
/// .and_modify(|e| *e = json!("rust"))
|
||||
/// .or_insert(json!("cpp"));
|
||||
///
|
||||
/// assert_eq!(map["serde"], "cpp");
|
||||
///
|
||||
/// map.entry("serde")
|
||||
/// .and_modify(|e| *e = json!("rust"))
|
||||
/// .or_insert(json!("cpp"));
|
||||
///
|
||||
/// assert_eq!(map["serde"], "rust");
|
||||
/// ```
|
||||
pub fn and_modify<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(&mut Value),
|
||||
{
|
||||
match self {
|
||||
Entry::Occupied(mut entry) => {
|
||||
f(entry.get_mut());
|
||||
Entry::Occupied(entry)
|
||||
}
|
||||
Entry::Vacant(entry) => Entry::Vacant(entry),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VacantEntry<'a> {
|
||||
/// Gets a reference to the key that would be used when inserting a value
|
||||
/// through the VacantEntry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Vacant(vacant) => {
|
||||
/// assert_eq!(vacant.key(), &"serde");
|
||||
/// }
|
||||
/// Entry::Occupied(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn key(&self) -> &String {
|
||||
self.vacant.key()
|
||||
}
|
||||
|
||||
/// Sets the value of the entry with the VacantEntry's key, and returns a
|
||||
/// mutable reference to it.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Vacant(vacant) => {
|
||||
/// vacant.insert(json!("hoho"));
|
||||
/// }
|
||||
/// Entry::Occupied(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn insert(self, value: Value) -> &'a mut Value {
|
||||
self.vacant.insert(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> OccupiedEntry<'a> {
|
||||
/// Gets a reference to the key in the entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!(12));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(occupied) => {
|
||||
/// assert_eq!(occupied.key(), &"serde");
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn key(&self) -> &String {
|
||||
self.occupied.key()
|
||||
}
|
||||
|
||||
/// Gets a reference to the value in the entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!(12));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(occupied) => {
|
||||
/// assert_eq!(occupied.get(), 12);
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn get(&self) -> &Value {
|
||||
self.occupied.get()
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the value in the entry.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!([1, 2, 3]));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(mut occupied) => {
|
||||
/// occupied.get_mut().as_array_mut().unwrap().push(json!(4));
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(map["serde"].as_array().unwrap().len(), 4);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self) -> &mut Value {
|
||||
self.occupied.get_mut()
|
||||
}
|
||||
|
||||
/// Converts the entry into a mutable reference to its value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!([1, 2, 3]));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(mut occupied) => {
|
||||
/// occupied.into_mut().as_array_mut().unwrap().push(json!(4));
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
///
|
||||
/// assert_eq!(map["serde"].as_array().unwrap().len(), 4);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn into_mut(self) -> &'a mut Value {
|
||||
self.occupied.into_mut()
|
||||
}
|
||||
|
||||
/// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
|
||||
/// the entry's old value.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!(12));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(mut occupied) => {
|
||||
/// assert_eq!(occupied.insert(json!(13)), 12);
|
||||
/// assert_eq!(occupied.get(), 13);
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn insert(&mut self, value: Value) -> Value {
|
||||
self.occupied.insert(value)
|
||||
}
|
||||
|
||||
/// Takes the value of the entry out of the map, and returns it.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// use serde_json::map::Entry;
|
||||
///
|
||||
/// let mut map = serde_json::Map::new();
|
||||
/// map.insert("serde".to_owned(), json!(12));
|
||||
///
|
||||
/// match map.entry("serde") {
|
||||
/// Entry::Occupied(occupied) => {
|
||||
/// assert_eq!(occupied.remove(), 12);
|
||||
/// }
|
||||
/// Entry::Vacant(_) => unimplemented!(),
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn remove(self) -> Value {
|
||||
#[cfg(feature = "preserve_order")]
|
||||
return self.occupied.swap_remove();
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
return self.occupied.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<'a> IntoIterator for &'a Map<String, Value> {
|
||||
type Item = (&'a String, &'a Value);
|
||||
type IntoIter = Iter<'a>;
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Iter {
|
||||
iter: self.map.iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over a serde_json::Map's entries.
|
||||
pub struct Iter<'a> {
|
||||
iter: IterImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type IterImpl<'a> = btree_map::Iter<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>;
|
||||
|
||||
delegate_iterator!((Iter<'a>) => (&'a String, &'a Value));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl<'a> IntoIterator for &'a mut Map<String, Value> {
|
||||
type Item = (&'a String, &'a mut Value);
|
||||
type IntoIter = IterMut<'a>;
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IterMut {
|
||||
iter: self.map.iter_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mutable iterator over a serde_json::Map's entries.
|
||||
pub struct IterMut<'a> {
|
||||
iter: IterMutImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>;
|
||||
|
||||
delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl IntoIterator for Map<String, Value> {
|
||||
type Item = (String, Value);
|
||||
type IntoIter = IntoIter;
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
IntoIter {
|
||||
iter: self.map.into_iter(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An owning iterator over a serde_json::Map's entries.
|
||||
pub struct IntoIter {
|
||||
iter: IntoIterImpl,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type IntoIterImpl = btree_map::IntoIter<String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type IntoIterImpl = indexmap::map::IntoIter<String, Value>;
|
||||
|
||||
delegate_iterator!((IntoIter) => (String, Value));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// An iterator over a serde_json::Map's keys.
|
||||
pub struct Keys<'a> {
|
||||
iter: KeysImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type KeysImpl<'a> = btree_map::Keys<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>;
|
||||
|
||||
delegate_iterator!((Keys<'a>) => &'a String);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// An iterator over a serde_json::Map's values.
|
||||
pub struct Values<'a> {
|
||||
iter: ValuesImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type ValuesImpl<'a> = btree_map::Values<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>;
|
||||
|
||||
delegate_iterator!((Values<'a>) => &'a Value);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A mutable iterator over a serde_json::Map's values.
|
||||
pub struct ValuesMut<'a> {
|
||||
iter: ValuesMutImpl<'a>,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>;
|
||||
#[cfg(feature = "preserve_order")]
|
||||
type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>;
|
||||
|
||||
delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
|
801
vendor/serde_json/src/number.rs
vendored
Normal file
801
vendor/serde_json/src/number.rs
vendored
Normal file
@ -0,0 +1,801 @@
|
||||
use crate::de::ParserNumber;
|
||||
use crate::error::Error;
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
use crate::error::ErrorCode;
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
use alloc::borrow::ToOwned;
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
use alloc::string::{String, ToString};
|
||||
use core::fmt::{self, Debug, Display};
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
use core::hash::{Hash, Hasher};
|
||||
use serde::de::{self, Unexpected, Visitor};
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
use serde::de::{IntoDeserializer, MapAccess};
|
||||
use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
pub(crate) const TOKEN: &str = "$serde_json::private::Number";
|
||||
|
||||
/// Represents a JSON number, whether integer or floating point.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Number {
|
||||
n: N,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
#[derive(Copy, Clone)]
|
||||
enum N {
|
||||
PosInt(u64),
|
||||
/// Always less than zero.
|
||||
NegInt(i64),
|
||||
/// Always finite.
|
||||
Float(f64),
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
impl PartialEq for N {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(N::PosInt(a), N::PosInt(b)) => a == b,
|
||||
(N::NegInt(a), N::NegInt(b)) => a == b,
|
||||
(N::Float(a), N::Float(b)) => a == b,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementing Eq is fine since any float values are always finite.
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
impl Eq for N {}
|
||||
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
impl Hash for N {
|
||||
fn hash<H: Hasher>(&self, h: &mut H) {
|
||||
match *self {
|
||||
N::PosInt(i) => i.hash(h),
|
||||
N::NegInt(i) => i.hash(h),
|
||||
N::Float(f) => {
|
||||
if f == 0.0f64 {
|
||||
// There are 2 zero representations, +0 and -0, which
|
||||
// compare equal but have different bits. We use the +0 hash
|
||||
// for both so that hash(+0) == hash(-0).
|
||||
0.0f64.to_bits().hash(h);
|
||||
} else {
|
||||
f.to_bits().hash(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
type N = String;
|
||||
|
||||
impl Number {
|
||||
/// Returns true if the `Number` is an integer between `i64::MIN` and
|
||||
/// `i64::MAX`.
|
||||
///
|
||||
/// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
|
||||
/// return the integer value.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let big = i64::max_value() as u64 + 10;
|
||||
/// let v = json!({ "a": 64, "b": big, "c": 256.0 });
|
||||
///
|
||||
/// assert!(v["a"].is_i64());
|
||||
///
|
||||
/// // Greater than i64::MAX.
|
||||
/// assert!(!v["b"].is_i64());
|
||||
///
|
||||
/// // Numbers with a decimal point are not considered integers.
|
||||
/// assert!(!v["c"].is_i64());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_i64(&self) -> bool {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(v) => v <= i64::max_value() as u64,
|
||||
N::NegInt(_) => true,
|
||||
N::Float(_) => false,
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.as_i64().is_some()
|
||||
}
|
||||
|
||||
/// Returns true if the `Number` is an integer between zero and `u64::MAX`.
|
||||
///
|
||||
/// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
|
||||
/// return the integer value.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
|
||||
///
|
||||
/// assert!(v["a"].is_u64());
|
||||
///
|
||||
/// // Negative integer.
|
||||
/// assert!(!v["b"].is_u64());
|
||||
///
|
||||
/// // Numbers with a decimal point are not considered integers.
|
||||
/// assert!(!v["c"].is_u64());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_u64(&self) -> bool {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(_) => true,
|
||||
N::NegInt(_) | N::Float(_) => false,
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.as_u64().is_some()
|
||||
}
|
||||
|
||||
/// Returns true if the `Number` can be represented by f64.
|
||||
///
|
||||
/// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to
|
||||
/// return the floating point value.
|
||||
///
|
||||
/// Currently this function returns true if and only if both `is_i64` and
|
||||
/// `is_u64` return false but this is not a guarantee in the future.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
|
||||
///
|
||||
/// assert!(v["a"].is_f64());
|
||||
///
|
||||
/// // Integers.
|
||||
/// assert!(!v["b"].is_f64());
|
||||
/// assert!(!v["c"].is_f64());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_f64(&self) -> bool {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::Float(_) => true,
|
||||
N::PosInt(_) | N::NegInt(_) => false,
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
for c in self.n.chars() {
|
||||
if c == '.' || c == 'e' || c == 'E' {
|
||||
return self.n.parse::<f64>().ok().map_or(false, f64::is_finite);
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// If the `Number` is an integer, represent it as i64 if possible. Returns
|
||||
/// None otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let big = i64::max_value() as u64 + 10;
|
||||
/// let v = json!({ "a": 64, "b": big, "c": 256.0 });
|
||||
///
|
||||
/// assert_eq!(v["a"].as_i64(), Some(64));
|
||||
/// assert_eq!(v["b"].as_i64(), None);
|
||||
/// assert_eq!(v["c"].as_i64(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn as_i64(&self) -> Option<i64> {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(n) => {
|
||||
if n <= i64::max_value() as u64 {
|
||||
Some(n as i64)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
N::NegInt(n) => Some(n),
|
||||
N::Float(_) => None,
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.n.parse().ok()
|
||||
}
|
||||
|
||||
/// If the `Number` is an integer, represent it as u64 if possible. Returns
|
||||
/// None otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
|
||||
///
|
||||
/// assert_eq!(v["a"].as_u64(), Some(64));
|
||||
/// assert_eq!(v["b"].as_u64(), None);
|
||||
/// assert_eq!(v["c"].as_u64(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn as_u64(&self) -> Option<u64> {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(n) => Some(n),
|
||||
N::NegInt(_) | N::Float(_) => None,
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.n.parse().ok()
|
||||
}
|
||||
|
||||
/// Represents the number as f64 if possible. Returns None otherwise.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
|
||||
///
|
||||
/// assert_eq!(v["a"].as_f64(), Some(256.0));
|
||||
/// assert_eq!(v["b"].as_f64(), Some(64.0));
|
||||
/// assert_eq!(v["c"].as_f64(), Some(-64.0));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn as_f64(&self) -> Option<f64> {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(n) => Some(n as f64),
|
||||
N::NegInt(n) => Some(n as f64),
|
||||
N::Float(n) => Some(n),
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.n.parse::<f64>().ok().filter(|float| float.is_finite())
|
||||
}
|
||||
|
||||
/// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
|
||||
/// numbers.
|
||||
///
|
||||
/// ```
|
||||
/// # use std::f64;
|
||||
/// #
|
||||
/// # use serde_json::Number;
|
||||
/// #
|
||||
/// assert!(Number::from_f64(256.0).is_some());
|
||||
///
|
||||
/// assert!(Number::from_f64(f64::NAN).is_none());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn from_f64(f: f64) -> Option<Number> {
|
||||
if f.is_finite() {
|
||||
let n = {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
N::Float(f)
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
ryu::Buffer::new().format_finite(f).to_owned()
|
||||
}
|
||||
};
|
||||
Some(Number { n })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the exact original JSON representation that this Number was
|
||||
/// parsed from.
|
||||
///
|
||||
/// For numbers constructed not via parsing, such as by `From<i32>`, returns
|
||||
/// the JSON representation that serde\_json would serialize for this
|
||||
/// number.
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::Number;
|
||||
/// for value in [
|
||||
/// "7",
|
||||
/// "12.34",
|
||||
/// "34e-56789",
|
||||
/// "0.0123456789000000012345678900000001234567890000123456789",
|
||||
/// "343412345678910111213141516171819202122232425262728293034",
|
||||
/// "-343412345678910111213141516171819202122232425262728293031",
|
||||
/// ] {
|
||||
/// let number: Number = serde_json::from_str(value).unwrap();
|
||||
/// assert_eq!(number.as_str(), value);
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary_precision")))]
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.n
|
||||
}
|
||||
|
||||
pub(crate) fn as_f32(&self) -> Option<f32> {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
match self.n {
|
||||
N::PosInt(n) => Some(n as f32),
|
||||
N::NegInt(n) => Some(n as f32),
|
||||
N::Float(n) => Some(n as f32),
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
self.n.parse::<f32>().ok().filter(|float| float.is_finite())
|
||||
}
|
||||
|
||||
pub(crate) fn from_f32(f: f32) -> Option<Number> {
|
||||
if f.is_finite() {
|
||||
let n = {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
N::Float(f as f64)
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
ryu::Buffer::new().format_finite(f).to_owned()
|
||||
}
|
||||
};
|
||||
Some(Number { n })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
/// Not public API. Only tests use this.
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn from_string_unchecked(n: String) -> Self {
|
||||
Number { n }
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Number {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.n {
|
||||
N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
|
||||
N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
|
||||
N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
Display::fmt(&self.n, formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Number {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "Number({})", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Number {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self.n {
|
||||
N::PosInt(u) => serializer.serialize_u64(u),
|
||||
N::NegInt(i) => serializer.serialize_i64(i),
|
||||
N::Float(f) => serializer.serialize_f64(f),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
use serde::ser::SerializeStruct;
|
||||
|
||||
let mut s = tri!(serializer.serialize_struct(TOKEN, 1));
|
||||
tri!(s.serialize_field(TOKEN, &self.n));
|
||||
s.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Number {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct NumberVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for NumberVisitor {
|
||||
type Value = Number;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a JSON number")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
|
||||
Ok(value.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
|
||||
Ok(value.into())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_f64<E>(self, value: f64) -> Result<Number, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number"))
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
#[inline]
|
||||
fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error>
|
||||
where
|
||||
V: de::MapAccess<'de>,
|
||||
{
|
||||
let value = tri!(visitor.next_key::<NumberKey>());
|
||||
if value.is_none() {
|
||||
return Err(de::Error::invalid_type(Unexpected::Map, &self));
|
||||
}
|
||||
let v: NumberFromString = tri!(visitor.next_value());
|
||||
Ok(v.value)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_any(NumberVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
struct NumberKey;
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl<'de> de::Deserialize<'de> for NumberKey {
|
||||
fn deserialize<D>(deserializer: D) -> Result<NumberKey, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
struct FieldVisitor;
|
||||
|
||||
impl<'de> de::Visitor<'de> for FieldVisitor {
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("a valid number field")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<(), E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if s == TOKEN {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::custom("expected field with custom name"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tri!(deserializer.deserialize_identifier(FieldVisitor));
|
||||
Ok(NumberKey)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
pub struct NumberFromString {
|
||||
pub value: Number,
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl<'de> de::Deserialize<'de> for NumberFromString {
|
||||
fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
struct Visitor;
|
||||
|
||||
impl<'de> de::Visitor<'de> for Visitor {
|
||||
type Value = NumberFromString;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("string containing a number")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
let n = tri!(s.parse().map_err(de::Error::custom));
|
||||
Ok(NumberFromString { value: n })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
fn invalid_number() -> Error {
|
||||
Error::syntax(ErrorCode::InvalidNumber, 0, 0)
|
||||
}
|
||||
|
||||
macro_rules! deserialize_any {
|
||||
(@expand [$($num_string:tt)*]) => {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
#[inline]
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
match self.n {
|
||||
N::PosInt(u) => visitor.visit_u64(u),
|
||||
N::NegInt(i) => visitor.visit_i64(i),
|
||||
N::Float(f) => visitor.visit_f64(f),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
#[inline]
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where V: Visitor<'de>
|
||||
{
|
||||
if let Some(u) = self.as_u64() {
|
||||
return visitor.visit_u64(u);
|
||||
} else if let Some(i) = self.as_i64() {
|
||||
return visitor.visit_i64(i);
|
||||
} else if let Some(f) = self.as_f64() {
|
||||
if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n {
|
||||
return visitor.visit_f64(f);
|
||||
}
|
||||
}
|
||||
|
||||
visitor.visit_map(NumberDeserializer {
|
||||
number: Some(self.$($num_string)*),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
(owned) => {
|
||||
deserialize_any!(@expand [n]);
|
||||
};
|
||||
|
||||
(ref) => {
|
||||
deserialize_any!(@expand [n.clone()]);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! deserialize_number {
|
||||
($deserialize:ident => $visit:ident) => {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.$visit(tri!(self.n.parse().map_err(|_| invalid_number())))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<'de> Deserializer<'de> for Number {
|
||||
type Error = Error;
|
||||
|
||||
deserialize_any!(owned);
|
||||
|
||||
deserialize_number!(deserialize_i8 => visit_i8);
|
||||
deserialize_number!(deserialize_i16 => visit_i16);
|
||||
deserialize_number!(deserialize_i32 => visit_i32);
|
||||
deserialize_number!(deserialize_i64 => visit_i64);
|
||||
deserialize_number!(deserialize_i128 => visit_i128);
|
||||
deserialize_number!(deserialize_u8 => visit_u8);
|
||||
deserialize_number!(deserialize_u16 => visit_u16);
|
||||
deserialize_number!(deserialize_u32 => visit_u32);
|
||||
deserialize_number!(deserialize_u64 => visit_u64);
|
||||
deserialize_number!(deserialize_u128 => visit_u128);
|
||||
deserialize_number!(deserialize_f32 => visit_f32);
|
||||
deserialize_number!(deserialize_f64 => visit_f64);
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool char str string bytes byte_buf option unit unit_struct
|
||||
newtype_struct seq tuple tuple_struct map struct enum identifier
|
||||
ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, 'a> Deserializer<'de> for &'a Number {
|
||||
type Error = Error;
|
||||
|
||||
deserialize_any!(ref);
|
||||
|
||||
deserialize_number!(deserialize_i8 => visit_i8);
|
||||
deserialize_number!(deserialize_i16 => visit_i16);
|
||||
deserialize_number!(deserialize_i32 => visit_i32);
|
||||
deserialize_number!(deserialize_i64 => visit_i64);
|
||||
deserialize_number!(deserialize_i128 => visit_i128);
|
||||
deserialize_number!(deserialize_u8 => visit_u8);
|
||||
deserialize_number!(deserialize_u16 => visit_u16);
|
||||
deserialize_number!(deserialize_u32 => visit_u32);
|
||||
deserialize_number!(deserialize_u64 => visit_u64);
|
||||
deserialize_number!(deserialize_u128 => visit_u128);
|
||||
deserialize_number!(deserialize_f32 => visit_f32);
|
||||
deserialize_number!(deserialize_f64 => visit_f64);
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool char str string bytes byte_buf option unit unit_struct
|
||||
newtype_struct seq tuple tuple_struct map struct enum identifier
|
||||
ignored_any
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
pub(crate) struct NumberDeserializer {
|
||||
pub number: Option<String>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl<'de> MapAccess<'de> for NumberDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where
|
||||
K: de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.number.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
seed.deserialize(NumberFieldDeserializer).map(Some)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(self.number.take().unwrap().into_deserializer())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
struct NumberFieldDeserializer;
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl<'de> Deserializer<'de> for NumberFieldDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_borrowed_str(TOKEN)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
|
||||
bytes byte_buf map struct option unit newtype_struct ignored_any
|
||||
unit_struct tuple_struct tuple enum identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ParserNumber> for Number {
|
||||
fn from(value: ParserNumber) -> Self {
|
||||
let n = match value {
|
||||
ParserNumber::F64(f) => {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
N::Float(f)
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
f.to_string()
|
||||
}
|
||||
}
|
||||
ParserNumber::U64(u) => {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
N::PosInt(u)
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
u.to_string()
|
||||
}
|
||||
}
|
||||
ParserNumber::I64(i) => {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
N::NegInt(i)
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
i.to_string()
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
ParserNumber::String(s) => s,
|
||||
};
|
||||
Number { n }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_unsigned {
|
||||
(
|
||||
$($ty:ty),*
|
||||
) => {
|
||||
$(
|
||||
impl From<$ty> for Number {
|
||||
#[inline]
|
||||
fn from(u: $ty) -> Self {
|
||||
let n = {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{ N::PosInt(u as u64) }
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
itoa::Buffer::new().format(u).to_owned()
|
||||
}
|
||||
};
|
||||
Number { n }
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_from_signed {
|
||||
(
|
||||
$($ty:ty),*
|
||||
) => {
|
||||
$(
|
||||
impl From<$ty> for Number {
|
||||
#[inline]
|
||||
fn from(i: $ty) -> Self {
|
||||
let n = {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
{
|
||||
if i < 0 {
|
||||
N::NegInt(i as i64)
|
||||
} else {
|
||||
N::PosInt(i as u64)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
{
|
||||
itoa::Buffer::new().format(i).to_owned()
|
||||
}
|
||||
};
|
||||
Number { n }
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_unsigned!(u8, u16, u32, u64, usize);
|
||||
impl_from_signed!(i8, i16, i32, i64, isize);
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl_from_unsigned!(u128);
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
impl_from_signed!(i128);
|
||||
|
||||
impl Number {
|
||||
#[cfg(not(feature = "arbitrary_precision"))]
|
||||
#[cold]
|
||||
pub(crate) fn unexpected(&self) -> Unexpected {
|
||||
match self.n {
|
||||
N::PosInt(u) => Unexpected::Unsigned(u),
|
||||
N::NegInt(i) => Unexpected::Signed(i),
|
||||
N::Float(f) => Unexpected::Float(f),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
#[cold]
|
||||
pub(crate) fn unexpected(&self) -> Unexpected {
|
||||
Unexpected::Other("number")
|
||||
}
|
||||
}
|
777
vendor/serde_json/src/raw.rs
vendored
Normal file
777
vendor/serde_json/src/raw.rs
vendored
Normal file
@ -0,0 +1,777 @@
|
||||
use crate::error::Error;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
use core::mem;
|
||||
use serde::de::value::BorrowedStrDeserializer;
|
||||
use serde::de::{
|
||||
self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected,
|
||||
Visitor,
|
||||
};
|
||||
use serde::forward_to_deserialize_any;
|
||||
use serde::ser::{Serialize, SerializeStruct, Serializer};
|
||||
|
||||
/// Reference to a range of bytes encompassing a single valid JSON value in the
|
||||
/// input data.
|
||||
///
|
||||
/// A `RawValue` can be used to defer parsing parts of a payload until later,
|
||||
/// or to avoid parsing it at all in the case that part of the payload just
|
||||
/// needs to be transferred verbatim into a different output object.
|
||||
///
|
||||
/// When serializing, a value of this type will retain its original formatting
|
||||
/// and will not be minified or pretty-printed.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
|
||||
/// feature.
|
||||
///
|
||||
/// ```toml
|
||||
/// [dependencies]
|
||||
/// serde_json = { version = "1.0", features = ["raw_value"] }
|
||||
/// ```
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use serde::{Deserialize, Serialize};
|
||||
/// use serde_json::{Result, value::RawValue};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Input<'a> {
|
||||
/// code: u32,
|
||||
/// #[serde(borrow)]
|
||||
/// payload: &'a RawValue,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Output<'a> {
|
||||
/// info: (u32, &'a RawValue),
|
||||
/// }
|
||||
///
|
||||
/// // Efficiently rearrange JSON input containing separate "code" and "payload"
|
||||
/// // keys into a single "info" key holding an array of code and payload.
|
||||
/// //
|
||||
/// // This could be done equivalently using serde_json::Value as the type for
|
||||
/// // payload, but &RawValue will perform better because it does not require
|
||||
/// // memory allocation. The correct range of bytes is borrowed from the input
|
||||
/// // data and pasted verbatim into the output.
|
||||
/// fn rearrange(input: &str) -> Result<String> {
|
||||
/// let input: Input = serde_json::from_str(input)?;
|
||||
///
|
||||
/// let output = Output {
|
||||
/// info: (input.code, input.payload),
|
||||
/// };
|
||||
///
|
||||
/// serde_json::to_string(&output)
|
||||
/// }
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
|
||||
///
|
||||
/// assert_eq!(out, r#"{"info":[200,{}]}"#);
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// # Ownership
|
||||
///
|
||||
/// The typical usage of `RawValue` will be in the borrowed form:
|
||||
///
|
||||
/// ```
|
||||
/// # use serde::Deserialize;
|
||||
/// # use serde_json::value::RawValue;
|
||||
/// #
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct SomeStruct<'a> {
|
||||
/// #[serde(borrow)]
|
||||
/// raw_value: &'a RawValue,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// The borrowed form is suitable when deserializing through
|
||||
/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support
|
||||
/// borrowing from the input data without memory allocation.
|
||||
///
|
||||
/// When deserializing through [`serde_json::from_reader`] you will need to use
|
||||
/// the boxed form of `RawValue` instead. This is almost as efficient but
|
||||
/// involves buffering the raw value from the I/O stream into memory.
|
||||
///
|
||||
/// [`serde_json::from_str`]: ../fn.from_str.html
|
||||
/// [`serde_json::from_slice`]: ../fn.from_slice.html
|
||||
/// [`serde_json::from_reader`]: ../fn.from_reader.html
|
||||
///
|
||||
/// ```
|
||||
/// # use serde::Deserialize;
|
||||
/// # use serde_json::value::RawValue;
|
||||
/// #
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct SomeStruct {
|
||||
/// raw_value: Box<RawValue>,
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg_attr(not(doc), repr(transparent))]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
|
||||
pub struct RawValue {
|
||||
json: str,
|
||||
}
|
||||
|
||||
impl RawValue {
|
||||
fn from_borrowed(json: &str) -> &Self {
|
||||
unsafe { mem::transmute::<&str, &RawValue>(json) }
|
||||
}
|
||||
|
||||
fn from_owned(json: Box<str>) -> Box<Self> {
|
||||
unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
|
||||
}
|
||||
|
||||
fn into_owned(raw_value: Box<Self>) -> Box<str> {
|
||||
unsafe { mem::transmute::<Box<RawValue>, Box<str>>(raw_value) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Box<RawValue> {
|
||||
fn clone(&self) -> Self {
|
||||
(**self).to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOwned for RawValue {
|
||||
type Owned = Box<RawValue>;
|
||||
|
||||
fn to_owned(&self) -> Self::Owned {
|
||||
RawValue::from_owned(self.json.to_owned().into_boxed_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Box<RawValue> {
|
||||
fn default() -> Self {
|
||||
RawValue::from_borrowed("null").to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for RawValue {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter
|
||||
.debug_tuple("RawValue")
|
||||
.field(&format_args!("{}", &self.json))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for RawValue {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.write_str(&self.json)
|
||||
}
|
||||
}
|
||||
|
||||
impl RawValue {
|
||||
/// Convert an owned `String` of JSON data to an owned `RawValue`.
|
||||
///
|
||||
/// This function is equivalent to `serde_json::from_str::<Box<RawValue>>`
|
||||
/// except that we avoid an allocation and memcpy if both of the following
|
||||
/// are true:
|
||||
///
|
||||
/// - the input has no leading or trailing whitespace, and
|
||||
/// - the input has capacity equal to its length.
|
||||
pub fn from_string(json: String) -> Result<Box<Self>, Error> {
|
||||
let borrowed = tri!(crate::from_str::<&Self>(&json));
|
||||
if borrowed.json.len() < json.len() {
|
||||
return Ok(borrowed.to_owned());
|
||||
}
|
||||
Ok(Self::from_owned(json.into_boxed_str()))
|
||||
}
|
||||
|
||||
/// Access the JSON text underlying a raw value.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use serde::Deserialize;
|
||||
/// use serde_json::{Result, value::RawValue};
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// struct Response<'a> {
|
||||
/// code: u32,
|
||||
/// #[serde(borrow)]
|
||||
/// payload: &'a RawValue,
|
||||
/// }
|
||||
///
|
||||
/// fn process(input: &str) -> Result<()> {
|
||||
/// let response: Response = serde_json::from_str(input)?;
|
||||
///
|
||||
/// let payload = response.payload.get();
|
||||
/// if payload.starts_with('{') {
|
||||
/// // handle a payload which is a JSON map
|
||||
/// } else {
|
||||
/// // handle any other type
|
||||
/// }
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// process(r#" {"code": 200, "payload": {}} "#)?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn get(&self) -> &str {
|
||||
&self.json
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<RawValue>> for Box<str> {
|
||||
fn from(raw_value: Box<RawValue>) -> Self {
|
||||
RawValue::into_owned(raw_value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a `T` into a boxed `RawValue`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// // Upstream crate
|
||||
/// # #[derive(Serialize)]
|
||||
/// pub struct Thing {
|
||||
/// foo: String,
|
||||
/// bar: Option<String>,
|
||||
/// extra_data: Box<RawValue>,
|
||||
/// }
|
||||
///
|
||||
/// // Local crate
|
||||
/// use serde::Serialize;
|
||||
/// use serde_json::value::{to_raw_value, RawValue};
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct MyExtraData {
|
||||
/// a: u32,
|
||||
/// b: u32,
|
||||
/// }
|
||||
///
|
||||
/// let my_thing = Thing {
|
||||
/// foo: "FooVal".into(),
|
||||
/// bar: None,
|
||||
/// extra_data: to_raw_value(&MyExtraData { a: 1, b: 2 }).unwrap(),
|
||||
/// };
|
||||
/// # assert_eq!(
|
||||
/// # serde_json::to_value(my_thing).unwrap(),
|
||||
/// # serde_json::json!({
|
||||
/// # "foo": "FooVal",
|
||||
/// # "bar": null,
|
||||
/// # "extra_data": { "a": 1, "b": 2 }
|
||||
/// # })
|
||||
/// # );
|
||||
/// ```
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This conversion can fail if `T`'s implementation of `Serialize` decides to
|
||||
/// fail, or if `T` contains a map with non-string keys.
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::BTreeMap;
|
||||
///
|
||||
/// // The keys in this map are vectors, not strings.
|
||||
/// let mut map = BTreeMap::new();
|
||||
/// map.insert(vec![32, 64], "x86");
|
||||
///
|
||||
/// println!("{}", serde_json::value::to_raw_value(&map).unwrap_err());
|
||||
/// ```
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
|
||||
pub fn to_raw_value<T>(value: &T) -> Result<Box<RawValue>, Error>
|
||||
where
|
||||
T: ?Sized + Serialize,
|
||||
{
|
||||
let json_string = tri!(crate::to_string(value));
|
||||
Ok(RawValue::from_owned(json_string.into_boxed_str()))
|
||||
}
|
||||
|
||||
pub const TOKEN: &str = "$serde_json::private::RawValue";
|
||||
|
||||
impl Serialize for RawValue {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut s = tri!(serializer.serialize_struct(TOKEN, 1));
|
||||
tri!(s.serialize_field(TOKEN, &self.json));
|
||||
s.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct ReferenceVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for ReferenceVisitor {
|
||||
type Value = &'de RawValue;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "any valid JSON value")
|
||||
}
|
||||
|
||||
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
||||
where
|
||||
V: MapAccess<'de>,
|
||||
{
|
||||
let value = tri!(visitor.next_key::<RawKey>());
|
||||
if value.is_none() {
|
||||
return Err(de::Error::invalid_type(Unexpected::Map, &self));
|
||||
}
|
||||
visitor.next_value_seed(ReferenceFromString)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Box<RawValue> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct BoxedVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for BoxedVisitor {
|
||||
type Value = Box<RawValue>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(formatter, "any valid JSON value")
|
||||
}
|
||||
|
||||
fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
|
||||
where
|
||||
V: MapAccess<'de>,
|
||||
{
|
||||
let value = tri!(visitor.next_key::<RawKey>());
|
||||
if value.is_none() {
|
||||
return Err(de::Error::invalid_type(Unexpected::Map, &self));
|
||||
}
|
||||
visitor.next_value_seed(BoxedFromString)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct RawKey;
|
||||
|
||||
impl<'de> Deserialize<'de> for RawKey {
|
||||
fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct FieldVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for FieldVisitor {
|
||||
type Value = ();
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("raw value")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<(), E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
if s == TOKEN {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(de::Error::custom("unexpected raw value"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tri!(deserializer.deserialize_identifier(FieldVisitor));
|
||||
Ok(RawKey)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReferenceFromString;
|
||||
|
||||
impl<'de> DeserializeSeed<'de> for ReferenceFromString {
|
||||
type Value = &'de RawValue;
|
||||
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for ReferenceFromString {
|
||||
type Value = &'de RawValue;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("raw value")
|
||||
}
|
||||
|
||||
fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(RawValue::from_borrowed(s))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BoxedFromString;
|
||||
|
||||
impl<'de> DeserializeSeed<'de> for BoxedFromString {
|
||||
type Value = Box<RawValue>;
|
||||
|
||||
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Visitor<'de> for BoxedFromString {
|
||||
type Value = Box<RawValue>;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("raw value")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(RawValue::from_owned(s.to_owned().into_boxed_str()))
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok(RawValue::from_owned(s.into_boxed_str()))
|
||||
}
|
||||
}
|
||||
|
||||
struct RawKeyDeserializer;
|
||||
|
||||
impl<'de> Deserializer<'de> for RawKeyDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_borrowed_str(TOKEN)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
|
||||
bytes byte_buf map struct option unit newtype_struct ignored_any
|
||||
unit_struct tuple_struct tuple enum identifier
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OwnedRawDeserializer {
|
||||
pub raw_value: Option<String>,
|
||||
}
|
||||
|
||||
impl<'de> MapAccess<'de> for OwnedRawDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where
|
||||
K: de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.raw_value.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
seed.deserialize(RawKeyDeserializer).map(Some)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BorrowedRawDeserializer<'de> {
|
||||
pub raw_value: Option<&'de str>,
|
||||
}
|
||||
|
||||
impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where
|
||||
K: de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.raw_value.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
seed.deserialize(RawKeyDeserializer).map(Some)
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: de::DeserializeSeed<'de>,
|
||||
{
|
||||
seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> IntoDeserializer<'de, Error> for &'de RawValue {
|
||||
type Deserializer = &'de RawValue;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserializer<'de> for &'de RawValue {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_any(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_bool(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_i8(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_i16(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_i32(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_i64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_i128(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_u8(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_u16(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_u32(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_u64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_u128(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_f32(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_f64(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_char(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_str(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_string(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_bytes(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_byte_buf(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_option(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_unit(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_unit_struct(name, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_newtype_struct(name, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_seq(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_tuple(len, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_tuple_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
len: usize,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_tuple_struct(name, len, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_map(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_struct(name, fields, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
variants: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_enum(name, variants, visitor)
|
||||
}
|
||||
|
||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_identifier(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
crate::Deserializer::from_str(&self.json).deserialize_ignored_any(visitor)
|
||||
}
|
||||
}
|
1004
vendor/serde_json/src/read.rs
vendored
Normal file
1004
vendor/serde_json/src/read.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2247
vendor/serde_json/src/ser.rs
vendored
Normal file
2247
vendor/serde_json/src/ser.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1419
vendor/serde_json/src/value/de.rs
vendored
Normal file
1419
vendor/serde_json/src/value/de.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
278
vendor/serde_json/src/value/from.rs
vendored
Normal file
278
vendor/serde_json/src/value/from.rs
vendored
Normal file
@ -0,0 +1,278 @@
|
||||
use super::Value;
|
||||
use crate::map::Map;
|
||||
use crate::number::Number;
|
||||
use alloc::borrow::Cow;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
macro_rules! from_integer {
|
||||
($($ty:ident)*) => {
|
||||
$(
|
||||
impl From<$ty> for Value {
|
||||
fn from(n: $ty) -> Self {
|
||||
Value::Number(n.into())
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
from_integer! {
|
||||
i8 i16 i32 i64 isize
|
||||
u8 u16 u32 u64 usize
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary_precision")]
|
||||
from_integer! {
|
||||
i128 u128
|
||||
}
|
||||
|
||||
impl From<f32> for Value {
|
||||
/// Convert 32-bit floating point number to `Value::Number`, or
|
||||
/// `Value::Null` if infinite or NaN.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let f: f32 = 13.37;
|
||||
/// let x: Value = f.into();
|
||||
/// ```
|
||||
fn from(f: f32) -> Self {
|
||||
Number::from_f32(f).map_or(Value::Null, Value::Number)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Value {
|
||||
/// Convert 64-bit floating point number to `Value::Number`, or
|
||||
/// `Value::Null` if infinite or NaN.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let f: f64 = 13.37;
|
||||
/// let x: Value = f.into();
|
||||
/// ```
|
||||
fn from(f: f64) -> Self {
|
||||
Number::from_f64(f).map_or(Value::Null, Value::Number)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Value {
|
||||
/// Convert boolean to `Value::Bool`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let b = false;
|
||||
/// let x: Value = b.into();
|
||||
/// ```
|
||||
fn from(f: bool) -> Self {
|
||||
Value::Bool(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Value {
|
||||
/// Convert `String` to `Value::String`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let s: String = "lorem".to_string();
|
||||
/// let x: Value = s.into();
|
||||
/// ```
|
||||
fn from(f: String) -> Self {
|
||||
Value::String(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for Value {
|
||||
/// Convert string slice to `Value::String`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let s: &str = "lorem";
|
||||
/// let x: Value = s.into();
|
||||
/// ```
|
||||
fn from(f: &str) -> Self {
|
||||
Value::String(f.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<Cow<'a, str>> for Value {
|
||||
/// Convert copy-on-write string to `Value::String`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
/// use std::borrow::Cow;
|
||||
///
|
||||
/// let s: Cow<str> = Cow::Borrowed("lorem");
|
||||
/// let x: Value = s.into();
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
/// use std::borrow::Cow;
|
||||
///
|
||||
/// let s: Cow<str> = Cow::Owned("lorem".to_string());
|
||||
/// let x: Value = s.into();
|
||||
/// ```
|
||||
fn from(f: Cow<'a, str>) -> Self {
|
||||
Value::String(f.into_owned())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Number> for Value {
|
||||
/// Convert `Number` to `Value::Number`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::{Number, Value};
|
||||
///
|
||||
/// let n = Number::from(7);
|
||||
/// let x: Value = n.into();
|
||||
/// ```
|
||||
fn from(f: Number) -> Self {
|
||||
Value::Number(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Map<String, Value>> for Value {
|
||||
/// Convert map (with string keys) to `Value::Object`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::{Map, Value};
|
||||
///
|
||||
/// let mut m = Map::new();
|
||||
/// m.insert("Lorem".to_string(), "ipsum".into());
|
||||
/// let x: Value = m.into();
|
||||
/// ```
|
||||
fn from(f: Map<String, Value>) -> Self {
|
||||
Value::Object(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<Value>> From<Vec<T>> for Value {
|
||||
/// Convert a `Vec` to `Value::Array`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let v = vec!["lorem", "ipsum", "dolor"];
|
||||
/// let x: Value = v.into();
|
||||
/// ```
|
||||
fn from(f: Vec<T>) -> Self {
|
||||
Value::Array(f.into_iter().map(Into::into).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Into<Value>> From<&[T]> for Value {
|
||||
/// Convert a slice to `Value::Array`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let v: &[&str] = &["lorem", "ipsum", "dolor"];
|
||||
/// let x: Value = v.into();
|
||||
/// ```
|
||||
fn from(f: &[T]) -> Self {
|
||||
Value::Array(f.iter().cloned().map(Into::into).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Into<Value>> FromIterator<T> for Value {
|
||||
/// Create a `Value::Array` by collecting an iterator of array elements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let v = std::iter::repeat(42).take(5);
|
||||
/// let x: Value = v.collect();
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
|
||||
/// let x: Value = v.into_iter().collect();
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// use std::iter::FromIterator;
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
|
||||
/// ```
|
||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
||||
Value::Array(iter.into_iter().map(Into::into).collect())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value {
|
||||
/// Create a `Value::Object` by collecting an iterator of key-value pairs.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)];
|
||||
/// let x: Value = v.into_iter().collect();
|
||||
/// ```
|
||||
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
|
||||
Value::Object(
|
||||
iter.into_iter()
|
||||
.map(|(k, v)| (k.into(), v.into()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<()> for Value {
|
||||
/// Convert `()` to `Value::Null`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde_json::Value;
|
||||
///
|
||||
/// let u = ();
|
||||
/// let x: Value = u.into();
|
||||
/// ```
|
||||
fn from((): ()) -> Self {
|
||||
Value::Null
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Option<T>> for Value
|
||||
where
|
||||
T: Into<Value>,
|
||||
{
|
||||
fn from(opt: Option<T>) -> Self {
|
||||
match opt {
|
||||
None => Value::Null,
|
||||
Some(value) => Into::into(value),
|
||||
}
|
||||
}
|
||||
}
|
258
vendor/serde_json/src/value/index.rs
vendored
Normal file
258
vendor/serde_json/src/value/index.rs
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
use super::Value;
|
||||
use crate::map::Map;
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::string::String;
|
||||
use core::fmt::{self, Display};
|
||||
use core::ops;
|
||||
|
||||
/// A type that can be used to index into a `serde_json::Value`.
|
||||
///
|
||||
/// The [`get`] and [`get_mut`] methods of `Value` accept any type that
|
||||
/// implements `Index`, as does the [square-bracket indexing operator]. This
|
||||
/// trait is implemented for strings which are used as the index into a JSON
|
||||
/// map, and for `usize` which is used as the index into a JSON array.
|
||||
///
|
||||
/// [`get`]: ../enum.Value.html#method.get
|
||||
/// [`get_mut`]: ../enum.Value.html#method.get_mut
|
||||
/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E
|
||||
///
|
||||
/// This trait is sealed and cannot be implemented for types outside of
|
||||
/// `serde_json`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let data = json!({ "inner": [1, 2, 3] });
|
||||
///
|
||||
/// // Data is a JSON map so it can be indexed with a string.
|
||||
/// let inner = &data["inner"];
|
||||
///
|
||||
/// // Inner is a JSON array so it can be indexed with an integer.
|
||||
/// let first = &inner[0];
|
||||
///
|
||||
/// assert_eq!(first, 1);
|
||||
/// ```
|
||||
pub trait Index: private::Sealed {
|
||||
/// Return None if the key is not already in the array or object.
|
||||
#[doc(hidden)]
|
||||
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
|
||||
|
||||
/// Return None if the key is not already in the array or object.
|
||||
#[doc(hidden)]
|
||||
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
|
||||
|
||||
/// Panic if array index out of bounds. If key is not already in the object,
|
||||
/// insert it with a value of null. Panic if Value is a type that cannot be
|
||||
/// indexed into, except if Value is null then it can be treated as an empty
|
||||
/// object.
|
||||
#[doc(hidden)]
|
||||
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
|
||||
}
|
||||
|
||||
impl Index for usize {
|
||||
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
|
||||
match v {
|
||||
Value::Array(vec) => vec.get(*self),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
|
||||
match v {
|
||||
Value::Array(vec) => vec.get_mut(*self),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
|
||||
match v {
|
||||
Value::Array(vec) => {
|
||||
let len = vec.len();
|
||||
vec.get_mut(*self).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"cannot access index {} of JSON array of length {}",
|
||||
self, len
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => panic!("cannot access index {} of JSON {}", self, Type(v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Index for str {
|
||||
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
|
||||
match v {
|
||||
Value::Object(map) => map.get(self),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
|
||||
match v {
|
||||
Value::Object(map) => map.get_mut(self),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
|
||||
if let Value::Null = v {
|
||||
*v = Value::Object(Map::new());
|
||||
}
|
||||
match v {
|
||||
Value::Object(map) => map.entry(self.to_owned()).or_insert(Value::Null),
|
||||
_ => panic!("cannot access key {:?} in JSON {}", self, Type(v)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Index for String {
|
||||
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
|
||||
self[..].index_into(v)
|
||||
}
|
||||
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
|
||||
self[..].index_into_mut(v)
|
||||
}
|
||||
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
|
||||
self[..].index_or_insert(v)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Index for &T
|
||||
where
|
||||
T: ?Sized + Index,
|
||||
{
|
||||
fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
|
||||
(**self).index_into(v)
|
||||
}
|
||||
fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
|
||||
(**self).index_into_mut(v)
|
||||
}
|
||||
fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
|
||||
(**self).index_or_insert(v)
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent users from implementing the Index trait.
|
||||
mod private {
|
||||
pub trait Sealed {}
|
||||
impl Sealed for usize {}
|
||||
impl Sealed for str {}
|
||||
impl Sealed for alloc::string::String {}
|
||||
impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
|
||||
}
|
||||
|
||||
/// Used in panic messages.
|
||||
struct Type<'a>(&'a Value);
|
||||
|
||||
impl<'a> Display for Type<'a> {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self.0 {
|
||||
Value::Null => formatter.write_str("null"),
|
||||
Value::Bool(_) => formatter.write_str("boolean"),
|
||||
Value::Number(_) => formatter.write_str("number"),
|
||||
Value::String(_) => formatter.write_str("string"),
|
||||
Value::Array(_) => formatter.write_str("array"),
|
||||
Value::Object(_) => formatter.write_str("object"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The usual semantics of Index is to panic on invalid indexing.
|
||||
//
|
||||
// That said, the usual semantics are for things like Vec and BTreeMap which
|
||||
// have different use cases than Value. If you are working with a Vec, you know
|
||||
// that you are working with a Vec and you can get the len of the Vec and make
|
||||
// sure your indices are within bounds. The Value use cases are more
|
||||
// loosey-goosey. You got some JSON from an endpoint and you want to pull values
|
||||
// out of it. Outside of this Index impl, you already have the option of using
|
||||
// value.as_array() and working with the Vec directly, or matching on
|
||||
// Value::Array and getting the Vec directly. The Index impl means you can skip
|
||||
// that and index directly into the thing using a concise syntax. You don't have
|
||||
// to check the type, you don't have to check the len, it is all about what you
|
||||
// expect the Value to look like.
|
||||
//
|
||||
// Basically the use cases that would be well served by panicking here are
|
||||
// better served by using one of the other approaches: get and get_mut,
|
||||
// as_array, or match. The value of this impl is that it adds a way of working
|
||||
// with Value that is not well served by the existing approaches: concise and
|
||||
// careless and sometimes that is exactly what you want.
|
||||
impl<I> ops::Index<I> for Value
|
||||
where
|
||||
I: Index,
|
||||
{
|
||||
type Output = Value;
|
||||
|
||||
/// Index into a `serde_json::Value` using the syntax `value[0]` or
|
||||
/// `value["k"]`.
|
||||
///
|
||||
/// Returns `Value::Null` if the type of `self` does not match the type of
|
||||
/// the index, for example if the index is a string and `self` is an array
|
||||
/// or a number. Also returns `Value::Null` if the given key does not exist
|
||||
/// in the map or the given index is not within the bounds of the array.
|
||||
///
|
||||
/// For retrieving deeply nested values, you should have a look at the
|
||||
/// `Value::pointer` method.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let data = json!({
|
||||
/// "x": {
|
||||
/// "y": ["z", "zz"]
|
||||
/// }
|
||||
/// });
|
||||
///
|
||||
/// assert_eq!(data["x"]["y"], json!(["z", "zz"]));
|
||||
/// assert_eq!(data["x"]["y"][0], json!("z"));
|
||||
///
|
||||
/// assert_eq!(data["a"], json!(null)); // returns null for undefined values
|
||||
/// assert_eq!(data["a"]["b"], json!(null)); // does not panic
|
||||
/// ```
|
||||
fn index(&self, index: I) -> &Value {
|
||||
static NULL: Value = Value::Null;
|
||||
index.index_into(self).unwrap_or(&NULL)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> ops::IndexMut<I> for Value
|
||||
where
|
||||
I: Index,
|
||||
{
|
||||
/// Write into a `serde_json::Value` using the syntax `value[0] = ...` or
|
||||
/// `value["k"] = ...`.
|
||||
///
|
||||
/// If the index is a number, the value must be an array of length bigger
|
||||
/// than the index. Indexing into a value that is not an array or an array
|
||||
/// that is too small will panic.
|
||||
///
|
||||
/// If the index is a string, the value must be an object or null which is
|
||||
/// treated like an empty object. If the key is not already present in the
|
||||
/// object, it will be inserted with a value of null. Indexing into a value
|
||||
/// that is neither an object nor null will panic.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use serde_json::json;
|
||||
/// #
|
||||
/// let mut data = json!({ "x": 0 });
|
||||
///
|
||||
/// // replace an existing key
|
||||
/// data["x"] = json!(1);
|
||||
///
|
||||
/// // insert a new key
|
||||
/// data["y"] = json!([false, false, false]);
|
||||
///
|
||||
/// // replace an array value
|
||||
/// data["y"][0] = json!(true);
|
||||
///
|
||||
/// // inserted a deeply nested key
|
||||
/// data["a"]["b"]["c"]["d"] = json!(true);
|
||||
///
|
||||
/// println!("{}", data);
|
||||
/// ```
|
||||
fn index_mut(&mut self, index: I) -> &mut Value {
|
||||
index.index_or_insert(self)
|
||||
}
|
||||
}
|
1009
vendor/serde_json/src/value/mod.rs
vendored
Normal file
1009
vendor/serde_json/src/value/mod.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
vendor/serde_json/src/value/partial_eq.rs
vendored
Normal file
103
vendor/serde_json/src/value/partial_eq.rs
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
use super::Value;
|
||||
use alloc::string::String;
|
||||
|
||||
fn eq_i64(value: &Value, other: i64) -> bool {
|
||||
value.as_i64().map_or(false, |i| i == other)
|
||||
}
|
||||
|
||||
fn eq_u64(value: &Value, other: u64) -> bool {
|
||||
value.as_u64().map_or(false, |i| i == other)
|
||||
}
|
||||
|
||||
fn eq_f32(value: &Value, other: f32) -> bool {
|
||||
match value {
|
||||
Value::Number(n) => n.as_f32().map_or(false, |i| i == other),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_f64(value: &Value, other: f64) -> bool {
|
||||
value.as_f64().map_or(false, |i| i == other)
|
||||
}
|
||||
|
||||
fn eq_bool(value: &Value, other: bool) -> bool {
|
||||
value.as_bool().map_or(false, |i| i == other)
|
||||
}
|
||||
|
||||
fn eq_str(value: &Value, other: &str) -> bool {
|
||||
value.as_str().map_or(false, |i| i == other)
|
||||
}
|
||||
|
||||
impl PartialEq<str> for Value {
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
eq_str(self, other)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<&str> for Value {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
eq_str(self, *other)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Value> for str {
|
||||
fn eq(&self, other: &Value) -> bool {
|
||||
eq_str(other, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Value> for &str {
|
||||
fn eq(&self, other: &Value) -> bool {
|
||||
eq_str(other, *self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for Value {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
eq_str(self, other.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Value> for String {
|
||||
fn eq(&self, other: &Value) -> bool {
|
||||
eq_str(other, self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! partialeq_numeric {
|
||||
($($eq:ident [$($ty:ty)*])*) => {
|
||||
$($(
|
||||
impl PartialEq<$ty> for Value {
|
||||
fn eq(&self, other: &$ty) -> bool {
|
||||
$eq(self, *other as _)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Value> for $ty {
|
||||
fn eq(&self, other: &Value) -> bool {
|
||||
$eq(other, *self as _)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<$ty> for &'a Value {
|
||||
fn eq(&self, other: &$ty) -> bool {
|
||||
$eq(*self, *other as _)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq<$ty> for &'a mut Value {
|
||||
fn eq(&self, other: &$ty) -> bool {
|
||||
$eq(*self, *other as _)
|
||||
}
|
||||
}
|
||||
)*)*
|
||||
}
|
||||
}
|
||||
|
||||
partialeq_numeric! {
|
||||
eq_i64[i8 i16 i32 i64 isize]
|
||||
eq_u64[u8 u16 u32 u64 usize]
|
||||
eq_f32[f32]
|
||||
eq_f64[f64]
|
||||
eq_bool[bool]
|
||||
}
|
1053
vendor/serde_json/src/value/ser.rs
vendored
Normal file
1053
vendor/serde_json/src/value/ser.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7
vendor/serde_json/tests/compiletest.rs
vendored
Normal file
7
vendor/serde_json/tests/compiletest.rs
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#[rustversion::attr(not(nightly), ignore)]
|
||||
#[cfg_attr(miri, ignore)]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/*.rs");
|
||||
}
|
81
vendor/serde_json/tests/debug.rs
vendored
Normal file
81
vendor/serde_json/tests/debug.rs
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
use indoc::indoc;
|
||||
use serde_json::{json, Number, Value};
|
||||
|
||||
#[test]
|
||||
fn number() {
|
||||
assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
|
||||
assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
|
||||
assert_eq!(
|
||||
format!("{:?}", Number::from_f64(1.0).unwrap()),
|
||||
"Number(1.0)"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_null() {
|
||||
assert_eq!(format!("{:?}", json!(null)), "Null");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_bool() {
|
||||
assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
|
||||
assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_number() {
|
||||
assert_eq!(format!("{:?}", json!(1)), "Number(1)");
|
||||
assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
|
||||
assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
|
||||
assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1"
|
||||
assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_string() {
|
||||
assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_array() {
|
||||
assert_eq!(format!("{:?}", json!([])), "Array []");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_object() {
|
||||
assert_eq!(format!("{:?}", json!({})), "Object {}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn error() {
|
||||
let err = serde_json::from_str::<Value>("{0}").unwrap_err();
|
||||
let expected = "Error(\"key must be a string\", line: 1, column: 2)";
|
||||
assert_eq!(format!("{:?}", err), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indented() {
|
||||
let j = json!({
|
||||
"Array": [true],
|
||||
"Bool": true,
|
||||
"EmptyArray": [],
|
||||
"EmptyObject": {},
|
||||
"Null": null,
|
||||
"Number": 1,
|
||||
"String": "...",
|
||||
});
|
||||
let expected = indoc! {r#"
|
||||
Object {
|
||||
"Array": Array [
|
||||
Bool(true),
|
||||
],
|
||||
"Bool": Bool(true),
|
||||
"EmptyArray": Array [],
|
||||
"EmptyObject": Object {},
|
||||
"Null": Null,
|
||||
"Number": Number(1),
|
||||
"String": String("..."),
|
||||
}"#
|
||||
};
|
||||
assert_eq!(format!("{:#?}", j), expected);
|
||||
}
|
48
vendor/serde_json/tests/lexical.rs
vendored
Normal file
48
vendor/serde_json/tests/lexical.rs
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
#![allow(
|
||||
clippy::cast_lossless,
|
||||
clippy::cast_possible_truncation,
|
||||
clippy::cast_possible_wrap,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_sign_loss,
|
||||
clippy::comparison_chain,
|
||||
clippy::doc_markdown,
|
||||
clippy::excessive_precision,
|
||||
clippy::float_cmp,
|
||||
clippy::if_not_else,
|
||||
clippy::let_underscore_untyped,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::needless_late_init,
|
||||
clippy::shadow_unrelated,
|
||||
clippy::similar_names,
|
||||
clippy::single_match_else,
|
||||
clippy::too_many_lines,
|
||||
clippy::unreadable_literal,
|
||||
clippy::unseparated_literal_suffix,
|
||||
clippy::wildcard_imports
|
||||
)]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[path = "../src/lexical/mod.rs"]
|
||||
mod lexical;
|
||||
|
||||
#[path = "lexical/algorithm.rs"]
|
||||
mod algorithm;
|
||||
|
||||
#[path = "lexical/exponent.rs"]
|
||||
mod exponent;
|
||||
|
||||
#[path = "lexical/float.rs"]
|
||||
mod float;
|
||||
|
||||
#[path = "lexical/math.rs"]
|
||||
mod math;
|
||||
|
||||
#[path = "lexical/num.rs"]
|
||||
mod num;
|
||||
|
||||
#[path = "lexical/parse.rs"]
|
||||
mod parse;
|
||||
|
||||
#[path = "lexical/rounding.rs"]
|
||||
mod rounding;
|
110
vendor/serde_json/tests/lexical/algorithm.rs
vendored
Normal file
110
vendor/serde_json/tests/lexical/algorithm.rs
vendored
Normal file
@ -0,0 +1,110 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::algorithm::*;
|
||||
use crate::lexical::num::Float;
|
||||
|
||||
#[test]
|
||||
fn float_fast_path_test() {
|
||||
// valid
|
||||
let mantissa = (1 << f32::MANTISSA_SIZE) - 1;
|
||||
let (min_exp, max_exp) = f32::exponent_limit();
|
||||
for exp in min_exp..=max_exp {
|
||||
let f = fast_path::<f32>(mantissa, exp);
|
||||
assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
|
||||
}
|
||||
|
||||
// Check slightly above valid exponents
|
||||
let f = fast_path::<f32>(123, 15);
|
||||
assert_eq!(f, Some(1.23e+17));
|
||||
|
||||
// Exponent is 1 too high, pushes over the mantissa.
|
||||
let f = fast_path::<f32>(123, 16);
|
||||
assert!(f.is_none());
|
||||
|
||||
// Mantissa is too large, checked_mul should overflow.
|
||||
let f = fast_path::<f32>(mantissa, 11);
|
||||
assert!(f.is_none());
|
||||
|
||||
// invalid exponents
|
||||
let (min_exp, max_exp) = f32::exponent_limit();
|
||||
let f = fast_path::<f32>(mantissa, min_exp - 1);
|
||||
assert!(f.is_none(), "exponent under min_exp");
|
||||
|
||||
let f = fast_path::<f32>(mantissa, max_exp + 1);
|
||||
assert!(f.is_none(), "exponent above max_exp");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_fast_path_test() {
|
||||
// valid
|
||||
let mantissa = (1 << f64::MANTISSA_SIZE) - 1;
|
||||
let (min_exp, max_exp) = f64::exponent_limit();
|
||||
for exp in min_exp..=max_exp {
|
||||
let f = fast_path::<f64>(mantissa, exp);
|
||||
assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
|
||||
}
|
||||
|
||||
// invalid exponents
|
||||
let (min_exp, max_exp) = f64::exponent_limit();
|
||||
let f = fast_path::<f64>(mantissa, min_exp - 1);
|
||||
assert!(f.is_none(), "exponent under min_exp");
|
||||
|
||||
let f = fast_path::<f64>(mantissa, max_exp + 1);
|
||||
assert!(f.is_none(), "exponent above max_exp");
|
||||
|
||||
assert_eq!(
|
||||
Some(0.04628372940652459),
|
||||
fast_path::<f64>(4628372940652459, -17)
|
||||
);
|
||||
assert_eq!(None, fast_path::<f64>(26383446160308229, -272));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn moderate_path_test() {
|
||||
let (f, valid) = moderate_path::<f64>(1234567890, -1, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.0);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(1234567891, -1, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.1);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(12345678912, -2, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.12);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(123456789123, -3, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.123);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(1234567891234, -4, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.1234);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(12345678912345, -5, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.12345);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(123456789123456, -6, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.123456);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(1234567891234567, -7, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.1234567);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(12345678912345679, -8, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 123456789.12345679);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(4628372940652459, -17, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 0.04628372940652459);
|
||||
|
||||
let (f, valid) = moderate_path::<f64>(26383446160308229, -272, false);
|
||||
assert!(valid, "should be valid");
|
||||
assert_eq!(f.into_float::<f64>(), 2.6383446160308229e-256);
|
||||
|
||||
let (_, valid) = moderate_path::<f64>(26383446160308230, -272, false);
|
||||
assert!(!valid, "should be invalid");
|
||||
}
|
54
vendor/serde_json/tests/lexical/exponent.rs
vendored
Normal file
54
vendor/serde_json/tests/lexical/exponent.rs
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::exponent::*;
|
||||
|
||||
#[test]
|
||||
fn scientific_exponent_test() {
|
||||
// 0 digits in the integer
|
||||
assert_eq!(scientific_exponent(0, 0, 5), -6);
|
||||
assert_eq!(scientific_exponent(10, 0, 5), 4);
|
||||
assert_eq!(scientific_exponent(-10, 0, 5), -16);
|
||||
|
||||
// >0 digits in the integer
|
||||
assert_eq!(scientific_exponent(0, 1, 5), 0);
|
||||
assert_eq!(scientific_exponent(0, 2, 5), 1);
|
||||
assert_eq!(scientific_exponent(0, 2, 20), 1);
|
||||
assert_eq!(scientific_exponent(10, 2, 20), 11);
|
||||
assert_eq!(scientific_exponent(-10, 2, 20), -9);
|
||||
|
||||
// Underflow
|
||||
assert_eq!(
|
||||
scientific_exponent(i32::min_value(), 0, 0),
|
||||
i32::min_value()
|
||||
);
|
||||
assert_eq!(
|
||||
scientific_exponent(i32::min_value(), 0, 5),
|
||||
i32::min_value()
|
||||
);
|
||||
|
||||
// Overflow
|
||||
assert_eq!(
|
||||
scientific_exponent(i32::max_value(), 0, 0),
|
||||
i32::max_value() - 1
|
||||
);
|
||||
assert_eq!(
|
||||
scientific_exponent(i32::max_value(), 5, 0),
|
||||
i32::max_value()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mantissa_exponent_test() {
|
||||
assert_eq!(mantissa_exponent(10, 5, 0), 5);
|
||||
assert_eq!(mantissa_exponent(0, 5, 0), -5);
|
||||
assert_eq!(
|
||||
mantissa_exponent(i32::max_value(), 5, 0),
|
||||
i32::max_value() - 5
|
||||
);
|
||||
assert_eq!(mantissa_exponent(i32::max_value(), 0, 5), i32::max_value());
|
||||
assert_eq!(mantissa_exponent(i32::min_value(), 5, 0), i32::min_value());
|
||||
assert_eq!(
|
||||
mantissa_exponent(i32::min_value(), 0, 5),
|
||||
i32::min_value() + 5
|
||||
);
|
||||
}
|
581
vendor/serde_json/tests/lexical/float.rs
vendored
Normal file
581
vendor/serde_json/tests/lexical/float.rs
vendored
Normal file
@ -0,0 +1,581 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::float::ExtendedFloat;
|
||||
use crate::lexical::rounding::round_nearest_tie_even;
|
||||
use std::{f32, f64};
|
||||
|
||||
// NORMALIZE
|
||||
|
||||
fn check_normalize(mant: u64, exp: i32, shift: u32, r_mant: u64, r_exp: i32) {
|
||||
let mut x = ExtendedFloat { mant, exp };
|
||||
assert_eq!(x.normalize(), shift);
|
||||
assert_eq!(
|
||||
x,
|
||||
ExtendedFloat {
|
||||
mant: r_mant,
|
||||
exp: r_exp
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalize_test() {
|
||||
// F32
|
||||
// 0
|
||||
check_normalize(0, 0, 0, 0, 0);
|
||||
|
||||
// min value
|
||||
check_normalize(1, -149, 63, 9223372036854775808, -212);
|
||||
|
||||
// 1.0e-40
|
||||
check_normalize(71362, -149, 47, 10043308644012916736, -196);
|
||||
|
||||
// 1.0e-20
|
||||
check_normalize(12379400, -90, 40, 13611294244890214400, -130);
|
||||
|
||||
// 1.0
|
||||
check_normalize(8388608, -23, 40, 9223372036854775808, -63);
|
||||
|
||||
// 1e20
|
||||
check_normalize(11368684, 43, 40, 12500000250510966784, 3);
|
||||
|
||||
// max value
|
||||
check_normalize(16777213, 104, 40, 18446740775174668288, 64);
|
||||
|
||||
// F64
|
||||
|
||||
// min value
|
||||
check_normalize(1, -1074, 63, 9223372036854775808, -1137);
|
||||
|
||||
// 1.0e-250
|
||||
check_normalize(6448907850777164, -883, 11, 13207363278391631872, -894);
|
||||
|
||||
// 1.0e-150
|
||||
check_normalize(7371020360979573, -551, 11, 15095849699286165504, -562);
|
||||
|
||||
// 1.0e-45
|
||||
check_normalize(6427752177035961, -202, 11, 13164036458569648128, -213);
|
||||
|
||||
// 1.0e-40
|
||||
check_normalize(4903985730770844, -185, 11, 10043362776618688512, -196);
|
||||
|
||||
// 1.0e-20
|
||||
check_normalize(6646139978924579, -119, 11, 13611294676837537792, -130);
|
||||
|
||||
// 1.0
|
||||
check_normalize(4503599627370496, -52, 11, 9223372036854775808, -63);
|
||||
|
||||
// 1e20
|
||||
check_normalize(6103515625000000, 14, 11, 12500000000000000000, 3);
|
||||
|
||||
// 1e40
|
||||
check_normalize(8271806125530277, 80, 11, 16940658945086007296, 69);
|
||||
|
||||
// 1e150
|
||||
check_normalize(5503284107318959, 446, 11, 11270725851789228032, 435);
|
||||
|
||||
// 1e250
|
||||
check_normalize(6290184345309700, 778, 11, 12882297539194265600, 767);
|
||||
|
||||
// max value
|
||||
check_normalize(9007199254740991, 971, 11, 18446744073709549568, 960);
|
||||
}
|
||||
|
||||
// ROUND
|
||||
|
||||
fn check_round_to_f32(mant: u64, exp: i32, r_mant: u64, r_exp: i32) {
|
||||
let mut x = ExtendedFloat { mant, exp };
|
||||
x.round_to_native::<f32, _>(round_nearest_tie_even);
|
||||
assert_eq!(
|
||||
x,
|
||||
ExtendedFloat {
|
||||
mant: r_mant,
|
||||
exp: r_exp
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_to_f32_test() {
|
||||
// This is lossy, so some of these values are **slightly** rounded.
|
||||
|
||||
// underflow
|
||||
check_round_to_f32(9223372036854775808, -213, 0, -149);
|
||||
|
||||
// min value
|
||||
check_round_to_f32(9223372036854775808, -212, 1, -149);
|
||||
|
||||
// 1.0e-40
|
||||
check_round_to_f32(10043308644012916736, -196, 71362, -149);
|
||||
|
||||
// 1.0e-20
|
||||
check_round_to_f32(13611294244890214400, -130, 12379400, -90);
|
||||
|
||||
// 1.0
|
||||
check_round_to_f32(9223372036854775808, -63, 8388608, -23);
|
||||
|
||||
// 1e20
|
||||
check_round_to_f32(12500000250510966784, 3, 11368684, 43);
|
||||
|
||||
// max value
|
||||
check_round_to_f32(18446740775174668288, 64, 16777213, 104);
|
||||
|
||||
// overflow
|
||||
check_round_to_f32(18446740775174668288, 65, 16777213, 105);
|
||||
}
|
||||
|
||||
fn check_round_to_f64(mant: u64, exp: i32, r_mant: u64, r_exp: i32) {
|
||||
let mut x = ExtendedFloat { mant, exp };
|
||||
x.round_to_native::<f64, _>(round_nearest_tie_even);
|
||||
assert_eq!(
|
||||
x,
|
||||
ExtendedFloat {
|
||||
mant: r_mant,
|
||||
exp: r_exp
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_to_f64_test() {
|
||||
// This is lossy, so some of these values are **slightly** rounded.
|
||||
|
||||
// underflow
|
||||
check_round_to_f64(9223372036854775808, -1138, 0, -1074);
|
||||
|
||||
// min value
|
||||
check_round_to_f64(9223372036854775808, -1137, 1, -1074);
|
||||
|
||||
// 1.0e-250
|
||||
check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551);
|
||||
|
||||
// 1.0e-150
|
||||
check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551);
|
||||
|
||||
// 1.0e-45
|
||||
check_round_to_f64(13164036458569648128, -213, 6427752177035961, -202);
|
||||
|
||||
// 1.0e-40
|
||||
check_round_to_f64(10043362776618688512, -196, 4903985730770844, -185);
|
||||
|
||||
// 1.0e-20
|
||||
check_round_to_f64(13611294676837537792, -130, 6646139978924579, -119);
|
||||
|
||||
// 1.0
|
||||
check_round_to_f64(9223372036854775808, -63, 4503599627370496, -52);
|
||||
|
||||
// 1e20
|
||||
check_round_to_f64(12500000000000000000, 3, 6103515625000000, 14);
|
||||
|
||||
// 1e40
|
||||
check_round_to_f64(16940658945086007296, 69, 8271806125530277, 80);
|
||||
|
||||
// 1e150
|
||||
check_round_to_f64(11270725851789228032, 435, 5503284107318959, 446);
|
||||
|
||||
// 1e250
|
||||
check_round_to_f64(12882297539194265600, 767, 6290184345309700, 778);
|
||||
|
||||
// max value
|
||||
check_round_to_f64(18446744073709549568, 960, 9007199254740991, 971);
|
||||
|
||||
// Bug fixes
|
||||
// 1.2345e-308
|
||||
check_round_to_f64(10234494226754558294, -1086, 2498655817078750, -1074);
|
||||
}
|
||||
|
||||
fn assert_normalized_eq(mut x: ExtendedFloat, mut y: ExtendedFloat) {
|
||||
x.normalize();
|
||||
y.normalize();
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_float() {
|
||||
let values: [f32; 26] = [
|
||||
1e-40, 2e-40, 1e-35, 2e-35, 1e-30, 2e-30, 1e-25, 2e-25, 1e-20, 2e-20, 1e-15, 2e-15, 1e-10,
|
||||
2e-10, 1e-5, 2e-5, 1.0, 2.0, 1e5, 2e5, 1e10, 2e10, 1e15, 2e15, 1e20, 2e20,
|
||||
];
|
||||
for value in &values {
|
||||
assert_normalized_eq(
|
||||
ExtendedFloat::from_float(*value),
|
||||
ExtendedFloat::from_float(*value as f64),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TO
|
||||
|
||||
// Sample of interesting numbers to check during standard test builds.
|
||||
const INTEGERS: [u64; 32] = [
|
||||
0, // 0x0
|
||||
1, // 0x1
|
||||
7, // 0x7
|
||||
15, // 0xF
|
||||
112, // 0x70
|
||||
119, // 0x77
|
||||
127, // 0x7F
|
||||
240, // 0xF0
|
||||
247, // 0xF7
|
||||
255, // 0xFF
|
||||
2032, // 0x7F0
|
||||
2039, // 0x7F7
|
||||
2047, // 0x7FF
|
||||
4080, // 0xFF0
|
||||
4087, // 0xFF7
|
||||
4095, // 0xFFF
|
||||
65520, // 0xFFF0
|
||||
65527, // 0xFFF7
|
||||
65535, // 0xFFFF
|
||||
1048560, // 0xFFFF0
|
||||
1048567, // 0xFFFF7
|
||||
1048575, // 0xFFFFF
|
||||
16777200, // 0xFFFFF0
|
||||
16777207, // 0xFFFFF7
|
||||
16777215, // 0xFFFFFF
|
||||
268435440, // 0xFFFFFF0
|
||||
268435447, // 0xFFFFFF7
|
||||
268435455, // 0xFFFFFFF
|
||||
4294967280, // 0xFFFFFFF0
|
||||
4294967287, // 0xFFFFFFF7
|
||||
4294967295, // 0xFFFFFFFF
|
||||
18446744073709551615, // 0xFFFFFFFFFFFFFFFF
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn to_f32_test() {
|
||||
// underflow
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -213,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 0.0);
|
||||
|
||||
// min value
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -212,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 1e-45);
|
||||
|
||||
// 1.0e-40
|
||||
let x = ExtendedFloat {
|
||||
mant: 10043308644012916736,
|
||||
exp: -196,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 1e-40);
|
||||
|
||||
// 1.0e-20
|
||||
let x = ExtendedFloat {
|
||||
mant: 13611294244890214400,
|
||||
exp: -130,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 1e-20);
|
||||
|
||||
// 1.0
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -63,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 1.0);
|
||||
|
||||
// 1e20
|
||||
let x = ExtendedFloat {
|
||||
mant: 12500000250510966784,
|
||||
exp: 3,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 1e20);
|
||||
|
||||
// max value
|
||||
let x = ExtendedFloat {
|
||||
mant: 18446740775174668288,
|
||||
exp: 64,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 3.402823e38);
|
||||
|
||||
// almost max, high exp
|
||||
let x = ExtendedFloat {
|
||||
mant: 1048575,
|
||||
exp: 108,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), 3.4028204e38);
|
||||
|
||||
// max value + 1
|
||||
let x = ExtendedFloat {
|
||||
mant: 16777216,
|
||||
exp: 104,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), f32::INFINITY);
|
||||
|
||||
// max value + 1
|
||||
let x = ExtendedFloat {
|
||||
mant: 1048576,
|
||||
exp: 108,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), f32::INFINITY);
|
||||
|
||||
// 1e40
|
||||
let x = ExtendedFloat {
|
||||
mant: 16940658945086007296,
|
||||
exp: 69,
|
||||
};
|
||||
assert_eq!(x.into_float::<f32>(), f32::INFINITY);
|
||||
|
||||
// Integers.
|
||||
for int in &INTEGERS {
|
||||
let fp = ExtendedFloat { mant: *int, exp: 0 };
|
||||
assert_eq!(fp.into_float::<f32>(), *int as f32, "{:?} as f32", *int);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_f64_test() {
|
||||
// underflow
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -1138,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 0.0);
|
||||
|
||||
// min value
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -1137,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 5e-324);
|
||||
|
||||
// 1.0e-250
|
||||
let x = ExtendedFloat {
|
||||
mant: 13207363278391631872,
|
||||
exp: -894,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e-250);
|
||||
|
||||
// 1.0e-150
|
||||
let x = ExtendedFloat {
|
||||
mant: 15095849699286165504,
|
||||
exp: -562,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e-150);
|
||||
|
||||
// 1.0e-45
|
||||
let x = ExtendedFloat {
|
||||
mant: 13164036458569648128,
|
||||
exp: -213,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e-45);
|
||||
|
||||
// 1.0e-40
|
||||
let x = ExtendedFloat {
|
||||
mant: 10043362776618688512,
|
||||
exp: -196,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e-40);
|
||||
|
||||
// 1.0e-20
|
||||
let x = ExtendedFloat {
|
||||
mant: 13611294676837537792,
|
||||
exp: -130,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e-20);
|
||||
|
||||
// 1.0
|
||||
let x = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -63,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1.0);
|
||||
|
||||
// 1e20
|
||||
let x = ExtendedFloat {
|
||||
mant: 12500000000000000000,
|
||||
exp: 3,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e20);
|
||||
|
||||
// 1e40
|
||||
let x = ExtendedFloat {
|
||||
mant: 16940658945086007296,
|
||||
exp: 69,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e40);
|
||||
|
||||
// 1e150
|
||||
let x = ExtendedFloat {
|
||||
mant: 11270725851789228032,
|
||||
exp: 435,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e150);
|
||||
|
||||
// 1e250
|
||||
let x = ExtendedFloat {
|
||||
mant: 12882297539194265600,
|
||||
exp: 767,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1e250);
|
||||
|
||||
// max value
|
||||
let x = ExtendedFloat {
|
||||
mant: 9007199254740991,
|
||||
exp: 971,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1.7976931348623157e308);
|
||||
|
||||
// max value
|
||||
let x = ExtendedFloat {
|
||||
mant: 18446744073709549568,
|
||||
exp: 960,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 1.7976931348623157e308);
|
||||
|
||||
// overflow
|
||||
let x = ExtendedFloat {
|
||||
mant: 9007199254740992,
|
||||
exp: 971,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), f64::INFINITY);
|
||||
|
||||
// overflow
|
||||
let x = ExtendedFloat {
|
||||
mant: 18446744073709549568,
|
||||
exp: 961,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), f64::INFINITY);
|
||||
|
||||
// Underflow
|
||||
// Adapted from failures in strtod.
|
||||
let x = ExtendedFloat {
|
||||
exp: -1139,
|
||||
mant: 18446744073709550712,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 0.0);
|
||||
|
||||
let x = ExtendedFloat {
|
||||
exp: -1139,
|
||||
mant: 18446744073709551460,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 0.0);
|
||||
|
||||
let x = ExtendedFloat {
|
||||
exp: -1138,
|
||||
mant: 9223372036854776103,
|
||||
};
|
||||
assert_eq!(x.into_float::<f64>(), 5e-324);
|
||||
|
||||
// Integers.
|
||||
for int in &INTEGERS {
|
||||
let fp = ExtendedFloat { mant: *int, exp: 0 };
|
||||
assert_eq!(fp.into_float::<f64>(), *int as f64, "{:?} as f64", *int);
|
||||
}
|
||||
}
|
||||
|
||||
// OPERATIONS
|
||||
|
||||
fn check_mul(a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) {
|
||||
let r = a.mul(&b);
|
||||
assert_eq!(r, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mul_test() {
|
||||
// Normalized (64-bit mantissa)
|
||||
let a = ExtendedFloat {
|
||||
mant: 13164036458569648128,
|
||||
exp: -213,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -62,
|
||||
};
|
||||
let c = ExtendedFloat {
|
||||
mant: 6582018229284824064,
|
||||
exp: -211,
|
||||
};
|
||||
check_mul(a, b, c);
|
||||
|
||||
// Check with integers
|
||||
// 64-bit mantissa
|
||||
let mut a = ExtendedFloat { mant: 10, exp: 0 };
|
||||
let mut b = ExtendedFloat { mant: 10, exp: 0 };
|
||||
a.normalize();
|
||||
b.normalize();
|
||||
assert_eq!(a.mul(&b).into_float::<f64>(), 100.0);
|
||||
|
||||
// Check both values need high bits set.
|
||||
let a = ExtendedFloat {
|
||||
mant: 1 << 32,
|
||||
exp: -31,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 1 << 32,
|
||||
exp: -31,
|
||||
};
|
||||
assert_eq!(a.mul(&b).into_float::<f64>(), 4.0);
|
||||
|
||||
// Check both values need high bits set.
|
||||
let a = ExtendedFloat {
|
||||
mant: 10 << 31,
|
||||
exp: -31,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 10 << 31,
|
||||
exp: -31,
|
||||
};
|
||||
assert_eq!(a.mul(&b).into_float::<f64>(), 100.0);
|
||||
}
|
||||
|
||||
fn check_imul(mut a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) {
|
||||
a.imul(&b);
|
||||
assert_eq!(a, c);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imul_test() {
|
||||
// Normalized (64-bit mantissa)
|
||||
let a = ExtendedFloat {
|
||||
mant: 13164036458569648128,
|
||||
exp: -213,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 9223372036854775808,
|
||||
exp: -62,
|
||||
};
|
||||
let c = ExtendedFloat {
|
||||
mant: 6582018229284824064,
|
||||
exp: -211,
|
||||
};
|
||||
check_imul(a, b, c);
|
||||
|
||||
// Check with integers
|
||||
// 64-bit mantissa
|
||||
let mut a = ExtendedFloat { mant: 10, exp: 0 };
|
||||
let mut b = ExtendedFloat { mant: 10, exp: 0 };
|
||||
a.normalize();
|
||||
b.normalize();
|
||||
a.imul(&b);
|
||||
assert_eq!(a.into_float::<f64>(), 100.0);
|
||||
|
||||
// Check both values need high bits set.
|
||||
let mut a = ExtendedFloat {
|
||||
mant: 1 << 32,
|
||||
exp: -31,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 1 << 32,
|
||||
exp: -31,
|
||||
};
|
||||
a.imul(&b);
|
||||
assert_eq!(a.into_float::<f64>(), 4.0);
|
||||
|
||||
// Check both values need high bits set.
|
||||
let mut a = ExtendedFloat {
|
||||
mant: 10 << 31,
|
||||
exp: -31,
|
||||
};
|
||||
let b = ExtendedFloat {
|
||||
mant: 10 << 31,
|
||||
exp: -31,
|
||||
};
|
||||
a.imul(&b);
|
||||
assert_eq!(a.into_float::<f64>(), 100.0);
|
||||
}
|
211
vendor/serde_json/tests/lexical/math.rs
vendored
Normal file
211
vendor/serde_json/tests/lexical/math.rs
vendored
Normal file
@ -0,0 +1,211 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::math::{Limb, Math};
|
||||
use std::cmp;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct Bigint {
|
||||
data: Vec<Limb>,
|
||||
}
|
||||
|
||||
impl Math for Bigint {
|
||||
fn data(&self) -> &Vec<Limb> {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn data_mut(&mut self) -> &mut Vec<Limb> {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(limb_width_32)]
|
||||
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
|
||||
x.iter().cloned().collect()
|
||||
}
|
||||
|
||||
#[cfg(limb_width_64)]
|
||||
pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
|
||||
let mut v = Vec::<Limb>::default();
|
||||
for xi in x.chunks(2) {
|
||||
match xi.len() {
|
||||
1 => v.push(xi[0] as u64),
|
||||
2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compare_test() {
|
||||
// Simple
|
||||
let x = Bigint {
|
||||
data: from_u32(&[1]),
|
||||
};
|
||||
let y = Bigint {
|
||||
data: from_u32(&[2]),
|
||||
};
|
||||
assert_eq!(x.compare(&y), cmp::Ordering::Less);
|
||||
assert_eq!(x.compare(&x), cmp::Ordering::Equal);
|
||||
assert_eq!(y.compare(&x), cmp::Ordering::Greater);
|
||||
|
||||
// Check asymmetric
|
||||
let x = Bigint {
|
||||
data: from_u32(&[5, 1]),
|
||||
};
|
||||
let y = Bigint {
|
||||
data: from_u32(&[2]),
|
||||
};
|
||||
assert_eq!(x.compare(&y), cmp::Ordering::Greater);
|
||||
assert_eq!(x.compare(&x), cmp::Ordering::Equal);
|
||||
assert_eq!(y.compare(&x), cmp::Ordering::Less);
|
||||
|
||||
// Check when we use reverse ordering properly.
|
||||
let x = Bigint {
|
||||
data: from_u32(&[5, 1, 9]),
|
||||
};
|
||||
let y = Bigint {
|
||||
data: from_u32(&[6, 2, 8]),
|
||||
};
|
||||
assert_eq!(x.compare(&y), cmp::Ordering::Greater);
|
||||
assert_eq!(x.compare(&x), cmp::Ordering::Equal);
|
||||
assert_eq!(y.compare(&x), cmp::Ordering::Less);
|
||||
|
||||
// Complex scenario, check it properly uses reverse ordering.
|
||||
let x = Bigint {
|
||||
data: from_u32(&[0, 1, 9]),
|
||||
};
|
||||
let y = Bigint {
|
||||
data: from_u32(&[4294967295, 0, 9]),
|
||||
};
|
||||
assert_eq!(x.compare(&y), cmp::Ordering::Greater);
|
||||
assert_eq!(x.compare(&x), cmp::Ordering::Equal);
|
||||
assert_eq!(y.compare(&x), cmp::Ordering::Less);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hi64_test() {
|
||||
assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false));
|
||||
assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false));
|
||||
assert_eq!(
|
||||
Bigint::from_u64(0xAB00000000).hi64(),
|
||||
(0xAB00000000000000, false)
|
||||
);
|
||||
assert_eq!(
|
||||
Bigint::from_u64(0xA23456789A).hi64(),
|
||||
(0xA23456789A000000, false)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bit_length_test() {
|
||||
let x = Bigint {
|
||||
data: from_u32(&[0, 0, 0, 1]),
|
||||
};
|
||||
assert_eq!(x.bit_length(), 97);
|
||||
|
||||
let x = Bigint {
|
||||
data: from_u32(&[0, 0, 0, 3]),
|
||||
};
|
||||
assert_eq!(x.bit_length(), 98);
|
||||
|
||||
let x = Bigint {
|
||||
data: from_u32(&[1 << 31]),
|
||||
};
|
||||
assert_eq!(x.bit_length(), 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iadd_small_test() {
|
||||
// Overflow check (single)
|
||||
// This should set all the internal data values to 0, the top
|
||||
// value to (1<<31), and the bottom value to (4>>1).
|
||||
// This is because the max_value + 1 leads to all 0s, we set the
|
||||
// topmost bit to 1.
|
||||
let mut x = Bigint {
|
||||
data: from_u32(&[4294967295]),
|
||||
};
|
||||
x.iadd_small(5);
|
||||
assert_eq!(x.data, from_u32(&[4, 1]));
|
||||
|
||||
// No overflow, single value
|
||||
let mut x = Bigint {
|
||||
data: from_u32(&[5]),
|
||||
};
|
||||
x.iadd_small(7);
|
||||
assert_eq!(x.data, from_u32(&[12]));
|
||||
|
||||
// Single carry, internal overflow
|
||||
let mut x = Bigint::from_u64(0x80000000FFFFFFFF);
|
||||
x.iadd_small(7);
|
||||
assert_eq!(x.data, from_u32(&[6, 0x80000001]));
|
||||
|
||||
// Double carry, overflow
|
||||
let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF);
|
||||
x.iadd_small(7);
|
||||
assert_eq!(x.data, from_u32(&[6, 0, 1]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn imul_small_test() {
|
||||
// No overflow check, 1-int.
|
||||
let mut x = Bigint {
|
||||
data: from_u32(&[5]),
|
||||
};
|
||||
x.imul_small(7);
|
||||
assert_eq!(x.data, from_u32(&[35]));
|
||||
|
||||
// No overflow check, 2-ints.
|
||||
let mut x = Bigint::from_u64(0x4000000040000);
|
||||
x.imul_small(5);
|
||||
assert_eq!(x.data, from_u32(&[0x00140000, 0x140000]));
|
||||
|
||||
// Overflow, 1 carry.
|
||||
let mut x = Bigint {
|
||||
data: from_u32(&[0x33333334]),
|
||||
};
|
||||
x.imul_small(5);
|
||||
assert_eq!(x.data, from_u32(&[4, 1]));
|
||||
|
||||
// Overflow, 1 carry, internal.
|
||||
let mut x = Bigint::from_u64(0x133333334);
|
||||
x.imul_small(5);
|
||||
assert_eq!(x.data, from_u32(&[4, 6]));
|
||||
|
||||
// Overflow, 2 carries.
|
||||
let mut x = Bigint::from_u64(0x3333333333333334);
|
||||
x.imul_small(5);
|
||||
assert_eq!(x.data, from_u32(&[4, 0, 1]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shl_test() {
|
||||
// Pattern generated via `''.join(["1" +"0"*i for i in range(20)])`
|
||||
let mut big = Bigint {
|
||||
data: from_u32(&[0xD2210408]),
|
||||
};
|
||||
big.ishl(5);
|
||||
assert_eq!(big.data, from_u32(&[0x44208100, 0x1A]));
|
||||
big.ishl(32);
|
||||
assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A]));
|
||||
big.ishl(27);
|
||||
assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408]));
|
||||
|
||||
// 96-bits of previous pattern
|
||||
let mut big = Bigint {
|
||||
data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]),
|
||||
};
|
||||
big.ishl(5);
|
||||
assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A]));
|
||||
big.ishl(32);
|
||||
assert_eq!(
|
||||
big.data,
|
||||
from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A])
|
||||
);
|
||||
big.ishl(27);
|
||||
assert_eq!(
|
||||
big.data,
|
||||
from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408])
|
||||
);
|
||||
}
|
76
vendor/serde_json/tests/lexical/num.rs
vendored
Normal file
76
vendor/serde_json/tests/lexical/num.rs
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::num::{AsPrimitive, Float, Integer, Number};
|
||||
|
||||
fn check_as_primitive<T: AsPrimitive>(t: T) {
|
||||
let _: u32 = t.as_u32();
|
||||
let _: u64 = t.as_u64();
|
||||
let _: u128 = t.as_u128();
|
||||
let _: usize = t.as_usize();
|
||||
let _: f32 = t.as_f32();
|
||||
let _: f64 = t.as_f64();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn as_primitive_test() {
|
||||
check_as_primitive(1u32);
|
||||
check_as_primitive(1u64);
|
||||
check_as_primitive(1u128);
|
||||
check_as_primitive(1usize);
|
||||
check_as_primitive(1f32);
|
||||
check_as_primitive(1f64);
|
||||
}
|
||||
|
||||
fn check_number<T: Number>(x: T, y: T) {
|
||||
// Copy, partialeq, partialord
|
||||
let _ = x;
|
||||
assert!(x < y);
|
||||
assert!(x != y);
|
||||
|
||||
// Operations
|
||||
let _ = y + x;
|
||||
|
||||
// Conversions already tested.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn number_test() {
|
||||
check_number(1u32, 5);
|
||||
check_number(1u64, 5);
|
||||
check_number(1u128, 5);
|
||||
check_number(1usize, 5);
|
||||
check_number(1f32, 5.0);
|
||||
check_number(1f64, 5.0);
|
||||
}
|
||||
|
||||
fn check_integer<T: Integer>(x: T) {
|
||||
// Bitwise operations
|
||||
let _ = x & T::ZERO;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn integer_test() {
|
||||
check_integer(65u32);
|
||||
check_integer(65u64);
|
||||
check_integer(65u128);
|
||||
check_integer(65usize);
|
||||
}
|
||||
|
||||
fn check_float<T: Float>(x: T) {
|
||||
// Check functions
|
||||
let _ = x.pow10(5);
|
||||
let _ = x.to_bits();
|
||||
assert!(T::from_bits(x.to_bits()) == x);
|
||||
|
||||
// Check properties
|
||||
let _ = x.to_bits() & T::SIGN_MASK;
|
||||
let _ = x.to_bits() & T::EXPONENT_MASK;
|
||||
let _ = x.to_bits() & T::HIDDEN_BIT_MASK;
|
||||
let _ = x.to_bits() & T::MANTISSA_MASK;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn float_test() {
|
||||
check_float(123f32);
|
||||
check_float(123f64);
|
||||
}
|
204
vendor/serde_json/tests/lexical/parse.rs
vendored
Normal file
204
vendor/serde_json/tests/lexical/parse.rs
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::num::Float;
|
||||
use crate::lexical::{parse_concise_float, parse_truncated_float};
|
||||
use core::f64;
|
||||
use core::fmt::Debug;
|
||||
|
||||
fn check_concise_float<F>(mantissa: u64, exponent: i32, expected: F)
|
||||
where
|
||||
F: Float + Debug,
|
||||
{
|
||||
assert_eq!(parse_concise_float::<F>(mantissa, exponent), expected);
|
||||
}
|
||||
|
||||
fn check_truncated_float<F>(integer: &str, fraction: &str, exponent: i32, expected: F)
|
||||
where
|
||||
F: Float + Debug,
|
||||
{
|
||||
let integer = integer.as_bytes();
|
||||
let fraction = fraction.as_bytes();
|
||||
assert_eq!(
|
||||
parse_truncated_float::<F>(integer, fraction, exponent),
|
||||
expected,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_f32_test() {
|
||||
check_concise_float(0, 0, 0.0_f32);
|
||||
check_concise_float(12345, -4, 1.2345_f32);
|
||||
check_concise_float(12345, -3, 12.345_f32);
|
||||
check_concise_float(123456789, -4, 12345.6789_f32);
|
||||
check_concise_float(12345, 6, 1.2345e10_f32);
|
||||
check_concise_float(12345, -42, 1.2345e-38_f32);
|
||||
|
||||
// Check expected rounding, using borderline cases.
|
||||
// Round-down, halfway
|
||||
check_concise_float(16777216, 0, 16777216.0_f32);
|
||||
check_concise_float(16777217, 0, 16777216.0_f32);
|
||||
check_concise_float(16777218, 0, 16777218.0_f32);
|
||||
check_concise_float(33554432, 0, 33554432.0_f32);
|
||||
check_concise_float(33554434, 0, 33554432.0_f32);
|
||||
check_concise_float(33554436, 0, 33554436.0_f32);
|
||||
check_concise_float(17179869184, 0, 17179869184.0_f32);
|
||||
check_concise_float(17179870208, 0, 17179869184.0_f32);
|
||||
check_concise_float(17179871232, 0, 17179871232.0_f32);
|
||||
|
||||
// Round-up, halfway
|
||||
check_concise_float(16777218, 0, 16777218.0_f32);
|
||||
check_concise_float(16777219, 0, 16777220.0_f32);
|
||||
check_concise_float(16777220, 0, 16777220.0_f32);
|
||||
|
||||
check_concise_float(33554436, 0, 33554436.0_f32);
|
||||
check_concise_float(33554438, 0, 33554440.0_f32);
|
||||
check_concise_float(33554440, 0, 33554440.0_f32);
|
||||
|
||||
check_concise_float(17179871232, 0, 17179871232.0_f32);
|
||||
check_concise_float(17179872256, 0, 17179873280.0_f32);
|
||||
check_concise_float(17179873280, 0, 17179873280.0_f32);
|
||||
|
||||
// Round-up, above halfway
|
||||
check_concise_float(33554435, 0, 33554436.0_f32);
|
||||
check_concise_float(17179870209, 0, 17179871232.0_f32);
|
||||
|
||||
// Check exactly halfway, round-up at halfway
|
||||
check_truncated_float("1", "00000017881393432617187499", 0, 1.0000001_f32);
|
||||
check_truncated_float("1", "000000178813934326171875", 0, 1.0000002_f32);
|
||||
check_truncated_float("1", "00000017881393432617187501", 0, 1.0000002_f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_f64_test() {
|
||||
check_concise_float(0, 0, 0.0_f64);
|
||||
check_concise_float(12345, -4, 1.2345_f64);
|
||||
check_concise_float(12345, -3, 12.345_f64);
|
||||
check_concise_float(123456789, -4, 12345.6789_f64);
|
||||
check_concise_float(12345, 6, 1.2345e10_f64);
|
||||
check_concise_float(12345, -312, 1.2345e-308_f64);
|
||||
|
||||
// Check expected rounding, using borderline cases.
|
||||
// Round-down, halfway
|
||||
check_concise_float(9007199254740992, 0, 9007199254740992.0_f64);
|
||||
check_concise_float(9007199254740993, 0, 9007199254740992.0_f64);
|
||||
check_concise_float(9007199254740994, 0, 9007199254740994.0_f64);
|
||||
|
||||
check_concise_float(18014398509481984, 0, 18014398509481984.0_f64);
|
||||
check_concise_float(18014398509481986, 0, 18014398509481984.0_f64);
|
||||
check_concise_float(18014398509481988, 0, 18014398509481988.0_f64);
|
||||
|
||||
check_concise_float(9223372036854775808, 0, 9223372036854775808.0_f64);
|
||||
check_concise_float(9223372036854776832, 0, 9223372036854775808.0_f64);
|
||||
check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64);
|
||||
|
||||
check_truncated_float(
|
||||
"11417981541647679048466287755595961091061972992",
|
||||
"",
|
||||
0,
|
||||
11417981541647679048466287755595961091061972992.0_f64,
|
||||
);
|
||||
check_truncated_float(
|
||||
"11417981541647680316116887983825362587765178368",
|
||||
"",
|
||||
0,
|
||||
11417981541647679048466287755595961091061972992.0_f64,
|
||||
);
|
||||
check_truncated_float(
|
||||
"11417981541647681583767488212054764084468383744",
|
||||
"",
|
||||
0,
|
||||
11417981541647681583767488212054764084468383744.0_f64,
|
||||
);
|
||||
|
||||
// Round-up, halfway
|
||||
check_concise_float(9007199254740994, 0, 9007199254740994.0_f64);
|
||||
check_concise_float(9007199254740995, 0, 9007199254740996.0_f64);
|
||||
check_concise_float(9007199254740996, 0, 9007199254740996.0_f64);
|
||||
|
||||
check_concise_float(18014398509481988, 0, 18014398509481988.0_f64);
|
||||
check_concise_float(18014398509481990, 0, 18014398509481992.0_f64);
|
||||
check_concise_float(18014398509481992, 0, 18014398509481992.0_f64);
|
||||
|
||||
check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64);
|
||||
check_concise_float(9223372036854778880, 0, 9223372036854779904.0_f64);
|
||||
check_concise_float(9223372036854779904, 0, 9223372036854779904.0_f64);
|
||||
|
||||
check_truncated_float(
|
||||
"11417981541647681583767488212054764084468383744",
|
||||
"",
|
||||
0,
|
||||
11417981541647681583767488212054764084468383744.0_f64,
|
||||
);
|
||||
check_truncated_float(
|
||||
"11417981541647682851418088440284165581171589120",
|
||||
"",
|
||||
0,
|
||||
11417981541647684119068688668513567077874794496.0_f64,
|
||||
);
|
||||
check_truncated_float(
|
||||
"11417981541647684119068688668513567077874794496",
|
||||
"",
|
||||
0,
|
||||
11417981541647684119068688668513567077874794496.0_f64,
|
||||
);
|
||||
|
||||
// Round-up, above halfway
|
||||
check_concise_float(9223372036854776833, 0, 9223372036854777856.0_f64);
|
||||
check_truncated_float(
|
||||
"11417981541647680316116887983825362587765178369",
|
||||
"",
|
||||
0,
|
||||
11417981541647681583767488212054764084468383744.0_f64,
|
||||
);
|
||||
|
||||
// Rounding error
|
||||
// Adapted from failures in strtod.
|
||||
check_concise_float(22250738585072014, -324, 2.2250738585072014e-308_f64);
|
||||
check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187499", -308, 2.225073858507201e-308_f64);
|
||||
check_truncated_float("2", "22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875", -308, 2.2250738585072014e-308_f64);
|
||||
check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187501", -308, 2.2250738585072014e-308_f64);
|
||||
check_truncated_float("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", "9999999999999999999999999999999999999999999999999999999999999999999999", 0, 1.7976931348623157e+308_f64);
|
||||
check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999", -324, 5.0e-324_f64);
|
||||
check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375", -324, 1.0e-323_f64);
|
||||
check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001", -324, 1.0e-323_f64);
|
||||
check_truncated_float("", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125", 0, 0.0_f64);
|
||||
|
||||
// Rounding error
|
||||
// Adapted from:
|
||||
// https://www.exploringbinary.com/how-glibc-strtod-works/
|
||||
check_truncated_float("", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0, 2.2250738585072011e-308_f64);
|
||||
|
||||
// Rounding error
|
||||
// Adapted from test-parse-random failures.
|
||||
check_concise_float(1009, -31, 1.009e-28_f64);
|
||||
check_concise_float(18294, 304, f64::INFINITY);
|
||||
|
||||
// Rounding error
|
||||
// Adapted from a @dangrabcad's issue #20.
|
||||
check_concise_float(7689539722041643, 149, 7.689539722041643e164_f64);
|
||||
check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "", 0, 7.689539722041643e164_f64);
|
||||
check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 7.689539722041643e164_f64);
|
||||
|
||||
// Check other cases similar to @dangrabcad's issue #20.
|
||||
check_truncated_float("9223372036854776833", "0", 0, 9223372036854777856.0_f64);
|
||||
check_truncated_float(
|
||||
"11417981541647680316116887983825362587765178369",
|
||||
"0",
|
||||
0,
|
||||
11417981541647681583767488212054764084468383744.0_f64,
|
||||
);
|
||||
check_concise_float(90071992547409950, -1, 9007199254740996.0_f64);
|
||||
check_concise_float(180143985094819900, -1, 18014398509481992.0_f64);
|
||||
check_truncated_float("9223372036854778880", "0", 0, 9223372036854779904.0_f64);
|
||||
check_truncated_float(
|
||||
"11417981541647682851418088440284165581171589120",
|
||||
"0",
|
||||
0,
|
||||
11417981541647684119068688668513567077874794496.0_f64,
|
||||
);
|
||||
|
||||
// Check other cases ostensibly identified via proptest.
|
||||
check_truncated_float("71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
|
||||
check_truncated_float("126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
|
||||
check_truncated_float("38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
|
||||
}
|
316
vendor/serde_json/tests/lexical/rounding.rs
vendored
Normal file
316
vendor/serde_json/tests/lexical/rounding.rs
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
// Adapted from https://github.com/Alexhuszagh/rust-lexical.
|
||||
|
||||
use crate::lexical::float::ExtendedFloat;
|
||||
use crate::lexical::num::Float;
|
||||
use crate::lexical::rounding::*;
|
||||
|
||||
// MASKS
|
||||
|
||||
#[test]
|
||||
fn lower_n_mask_test() {
|
||||
assert_eq!(lower_n_mask(0u64), 0b0);
|
||||
assert_eq!(lower_n_mask(1u64), 0b1);
|
||||
assert_eq!(lower_n_mask(2u64), 0b11);
|
||||
assert_eq!(lower_n_mask(10u64), 0b1111111111);
|
||||
assert_eq!(lower_n_mask(32u64), 0b11111111111111111111111111111111);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lower_n_halfway_test() {
|
||||
assert_eq!(lower_n_halfway(0u64), 0b0);
|
||||
assert_eq!(lower_n_halfway(1u64), 0b1);
|
||||
assert_eq!(lower_n_halfway(2u64), 0b10);
|
||||
assert_eq!(lower_n_halfway(10u64), 0b1000000000);
|
||||
assert_eq!(lower_n_halfway(32u64), 0b10000000000000000000000000000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nth_bit_test() {
|
||||
assert_eq!(nth_bit(0u64), 0b1);
|
||||
assert_eq!(nth_bit(1u64), 0b10);
|
||||
assert_eq!(nth_bit(2u64), 0b100);
|
||||
assert_eq!(nth_bit(10u64), 0b10000000000);
|
||||
assert_eq!(nth_bit(31u64), 0b10000000000000000000000000000000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn internal_n_mask_test() {
|
||||
assert_eq!(internal_n_mask(1u64, 0u64), 0b0);
|
||||
assert_eq!(internal_n_mask(1u64, 1u64), 0b1);
|
||||
assert_eq!(internal_n_mask(2u64, 1u64), 0b10);
|
||||
assert_eq!(internal_n_mask(4u64, 2u64), 0b1100);
|
||||
assert_eq!(internal_n_mask(10u64, 2u64), 0b1100000000);
|
||||
assert_eq!(internal_n_mask(10u64, 4u64), 0b1111000000);
|
||||
assert_eq!(
|
||||
internal_n_mask(32u64, 4u64),
|
||||
0b11110000000000000000000000000000
|
||||
);
|
||||
}
|
||||
|
||||
// NEAREST ROUNDING
|
||||
|
||||
#[test]
|
||||
fn round_nearest_test() {
|
||||
// Check exactly halfway (b'1100000')
|
||||
let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
|
||||
let (above, halfway) = round_nearest(&mut fp, 6);
|
||||
assert!(!above);
|
||||
assert!(halfway);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
// Check above halfway (b'1100001')
|
||||
let mut fp = ExtendedFloat { mant: 0x61, exp: 0 };
|
||||
let (above, halfway) = round_nearest(&mut fp, 6);
|
||||
assert!(above);
|
||||
assert!(!halfway);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
// Check below halfway (b'1011111')
|
||||
let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 };
|
||||
let (above, halfway) = round_nearest(&mut fp, 6);
|
||||
assert!(!above);
|
||||
assert!(!halfway);
|
||||
assert_eq!(fp.mant, 1);
|
||||
}
|
||||
|
||||
// DIRECTED ROUNDING
|
||||
|
||||
#[test]
|
||||
fn round_downward_test() {
|
||||
// b0000000
|
||||
let mut fp = ExtendedFloat { mant: 0x00, exp: 0 };
|
||||
round_downward(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 0);
|
||||
|
||||
// b1000000
|
||||
let mut fp = ExtendedFloat { mant: 0x40, exp: 0 };
|
||||
round_downward(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
// b1100000
|
||||
let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
|
||||
round_downward(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
// b1110000
|
||||
let mut fp = ExtendedFloat { mant: 0x70, exp: 0 };
|
||||
round_downward(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_nearest_tie_even_test() {
|
||||
// Check round-up, halfway
|
||||
let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 2);
|
||||
|
||||
// Check round-down, halfway
|
||||
let mut fp = ExtendedFloat { mant: 0x20, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 0);
|
||||
|
||||
// Check round-up, above halfway
|
||||
let mut fp = ExtendedFloat { mant: 0x61, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 2);
|
||||
|
||||
let mut fp = ExtendedFloat { mant: 0x21, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
// Check round-down, below halfway
|
||||
let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 1);
|
||||
|
||||
let mut fp = ExtendedFloat { mant: 0x1F, exp: 0 };
|
||||
round_nearest_tie_even(&mut fp, 6);
|
||||
assert_eq!(fp.mant, 0);
|
||||
}
|
||||
|
||||
// HIGH-LEVEL
|
||||
|
||||
#[test]
|
||||
fn round_to_float_test() {
|
||||
// Denormal
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 1 << 63,
|
||||
exp: f64::DENORMAL_EXPONENT - 15,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 48);
|
||||
assert_eq!(fp.exp, f64::DENORMAL_EXPONENT);
|
||||
|
||||
// Halfway, round-down (b'1000000000000000000000000000000000000000000000000000010000000000')
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x8000000000000400,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 52);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Halfway, round-up (b'1000000000000000000000000000000000000000000000000000110000000000')
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x8000000000000C00,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 2);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Above halfway
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x8000000000000401,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 1);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x8000000000000C01,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 2);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Below halfway
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x80000000000003FF,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 52);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x8000000000000BFF,
|
||||
exp: -63,
|
||||
};
|
||||
round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 1);
|
||||
assert_eq!(fp.exp, -52);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn avoid_overflow_test() {
|
||||
// Avoid overflow, fails by 1
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0xFFFFFFFFFFFF,
|
||||
exp: f64::MAX_EXPONENT + 5,
|
||||
};
|
||||
avoid_overflow::<f64>(&mut fp);
|
||||
assert_eq!(fp.mant, 0xFFFFFFFFFFFF);
|
||||
assert_eq!(fp.exp, f64::MAX_EXPONENT + 5);
|
||||
|
||||
// Avoid overflow, succeeds
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0xFFFFFFFFFFFF,
|
||||
exp: f64::MAX_EXPONENT + 4,
|
||||
};
|
||||
avoid_overflow::<f64>(&mut fp);
|
||||
assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0);
|
||||
assert_eq!(fp.exp, f64::MAX_EXPONENT - 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn round_to_native_test() {
|
||||
// Overflow
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0xFFFFFFFFFFFF,
|
||||
exp: f64::MAX_EXPONENT + 4,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0);
|
||||
assert_eq!(fp.exp, f64::MAX_EXPONENT - 1);
|
||||
|
||||
// Need denormal
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 1,
|
||||
exp: f64::DENORMAL_EXPONENT + 48,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 48);
|
||||
assert_eq!(fp.exp, f64::DENORMAL_EXPONENT);
|
||||
|
||||
// Halfway, round-down (b'10000000000000000000000000000000000000000000000000000100000')
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x400000000000020,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 52);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Halfway, round-up (b'10000000000000000000000000000000000000000000000000001100000')
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x400000000000060,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 2);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Above halfway
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x400000000000021,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 1);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x400000000000061,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 2);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Below halfway
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x40000000000001F,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1 << 52);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
mant: 0x40000000000005F,
|
||||
exp: -58,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, (1 << 52) + 1);
|
||||
assert_eq!(fp.exp, -52);
|
||||
|
||||
// Underflow
|
||||
// Adapted from failures in strtod.
|
||||
let mut fp = ExtendedFloat {
|
||||
exp: -1139,
|
||||
mant: 18446744073709550712,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 0);
|
||||
assert_eq!(fp.exp, 0);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
exp: -1139,
|
||||
mant: 18446744073709551460,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 0);
|
||||
assert_eq!(fp.exp, 0);
|
||||
|
||||
let mut fp = ExtendedFloat {
|
||||
exp: -1138,
|
||||
mant: 9223372036854776103,
|
||||
};
|
||||
round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
|
||||
assert_eq!(fp.mant, 1);
|
||||
assert_eq!(fp.exp, -1074);
|
||||
}
|
61
vendor/serde_json/tests/macros/mod.rs
vendored
Normal file
61
vendor/serde_json/tests/macros/mod.rs
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
#![allow(unused_macro_rules)]
|
||||
|
||||
macro_rules! json_str {
|
||||
([]) => {
|
||||
"[]"
|
||||
};
|
||||
([ $e0:tt $(, $e:tt)* $(,)? ]) => {
|
||||
concat!("[",
|
||||
json_str!($e0),
|
||||
$(",", json_str!($e),)*
|
||||
"]")
|
||||
};
|
||||
({}) => {
|
||||
"{}"
|
||||
};
|
||||
({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
|
||||
concat!("{",
|
||||
stringify!($k0), ":", json_str!($v0),
|
||||
$(",", stringify!($k), ":", json_str!($v),)*
|
||||
"}")
|
||||
};
|
||||
(($other:tt)) => {
|
||||
$other
|
||||
};
|
||||
($other:tt) => {
|
||||
stringify!($other)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! pretty_str {
|
||||
($json:tt) => {
|
||||
pretty_str_impl!("", $json)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! pretty_str_impl {
|
||||
($indent:expr, []) => {
|
||||
"[]"
|
||||
};
|
||||
($indent:expr, [ $e0:tt $(, $e:tt)* $(,)? ]) => {
|
||||
concat!("[\n ",
|
||||
$indent, pretty_str_impl!(concat!(" ", $indent), $e0),
|
||||
$(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)*
|
||||
"\n", $indent, "]")
|
||||
};
|
||||
($indent:expr, {}) => {
|
||||
"{}"
|
||||
};
|
||||
($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
|
||||
concat!("{\n ",
|
||||
$indent, stringify!($k0), ": ", pretty_str_impl!(concat!(" ", $indent), $v0),
|
||||
$(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)*
|
||||
"\n", $indent, "}")
|
||||
};
|
||||
($indent:expr, ($other:tt)) => {
|
||||
$other
|
||||
};
|
||||
($indent:expr, $other:tt) => {
|
||||
stringify!($other)
|
||||
};
|
||||
}
|
46
vendor/serde_json/tests/map.rs
vendored
Normal file
46
vendor/serde_json/tests/map.rs
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
use serde_json::{from_str, Map, Value};
|
||||
|
||||
#[test]
|
||||
fn test_preserve_order() {
|
||||
// Sorted order
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
const EXPECTED: &[&str] = &["a", "b", "c"];
|
||||
|
||||
// Insertion order
|
||||
#[cfg(feature = "preserve_order")]
|
||||
const EXPECTED: &[&str] = &["b", "a", "c"];
|
||||
|
||||
let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
|
||||
let keys: Vec<_> = v.as_object().unwrap().keys().collect();
|
||||
assert_eq!(keys, EXPECTED);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_append() {
|
||||
// Sorted order
|
||||
#[cfg(not(feature = "preserve_order"))]
|
||||
const EXPECTED: &[&str] = &["a", "b", "c"];
|
||||
|
||||
// Insertion order
|
||||
#[cfg(feature = "preserve_order")]
|
||||
const EXPECTED: &[&str] = &["b", "a", "c"];
|
||||
|
||||
let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
|
||||
let val = v.as_object_mut().unwrap();
|
||||
let mut m = Map::new();
|
||||
m.append(val);
|
||||
let keys: Vec<_> = m.keys().collect();
|
||||
|
||||
assert_eq!(keys, EXPECTED);
|
||||
assert!(val.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_retain() {
|
||||
let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
|
||||
let val = v.as_object_mut().unwrap();
|
||||
val.retain(|k, _| k.as_str() != "b");
|
||||
|
||||
let keys: Vec<_> = val.keys().collect();
|
||||
assert_eq!(keys, &["a", "c"]);
|
||||
}
|
3
vendor/serde_json/tests/regression.rs
vendored
Normal file
3
vendor/serde_json/tests/regression.rs
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
mod regression {
|
||||
automod::dir!("tests/regression");
|
||||
}
|
12
vendor/serde_json/tests/regression/issue1004.rs
vendored
Normal file
12
vendor/serde_json/tests/regression/issue1004.rs
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#![cfg(feature = "arbitrary_precision")]
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let float = 5.55f32;
|
||||
let value = serde_json::to_value(float).unwrap();
|
||||
let json = serde_json::to_string(&value).unwrap();
|
||||
|
||||
// If the f32 were cast to f64 by Value before serialization, then this
|
||||
// would incorrectly serialize as 5.550000190734863.
|
||||
assert_eq!(json, "5.55");
|
||||
}
|
20
vendor/serde_json/tests/regression/issue520.rs
vendored
Normal file
20
vendor/serde_json/tests/regression/issue520.rs
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
#![allow(clippy::float_cmp)]
|
||||
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
enum E {
|
||||
Float(f32),
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let e = E::Float(159.1);
|
||||
let v = serde_json::to_value(e).unwrap();
|
||||
let e = serde_json::from_value::<E>(v).unwrap();
|
||||
|
||||
match e {
|
||||
E::Float(f) => assert_eq!(f, 159.1),
|
||||
}
|
||||
}
|
59
vendor/serde_json/tests/regression/issue795.rs
vendored
Normal file
59
vendor/serde_json/tests/regression/issue795.rs
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
#![allow(clippy::assertions_on_result_states)]
|
||||
|
||||
use serde::de::{
|
||||
Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor,
|
||||
};
|
||||
use serde_json::json;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Enum {
|
||||
Variant { x: u8 },
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Enum {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
struct EnumVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for EnumVisitor {
|
||||
type Value = Enum;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("enum Enum")
|
||||
}
|
||||
|
||||
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: EnumAccess<'de>,
|
||||
{
|
||||
let (IgnoredAny, variant) = data.variant()?;
|
||||
variant.struct_variant(&["x"], self)
|
||||
}
|
||||
|
||||
fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: MapAccess<'de>,
|
||||
{
|
||||
let mut x = 0;
|
||||
if let Some((IgnoredAny, value)) = data.next_entry()? {
|
||||
x = value;
|
||||
}
|
||||
Ok(Enum::Variant { x })
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_enum("Enum", &["Variant"], EnumVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let s = r#" {"Variant":{"x":0,"y":0}} "#;
|
||||
assert!(serde_json::from_str::<Enum>(s).is_err());
|
||||
|
||||
let j = json!({"Variant":{"x":0,"y":0}});
|
||||
assert!(serde_json::from_value::<Enum>(j).is_err());
|
||||
}
|
73
vendor/serde_json/tests/regression/issue845.rs
vendored
Normal file
73
vendor/serde_json/tests/regression/issue845.rs
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
#![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757
|
||||
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::fmt::{self, Display};
|
||||
use std::marker::PhantomData;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub struct NumberVisitor<T> {
|
||||
marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<'de, T> serde::de::Visitor<'de> for NumberVisitor<T>
|
||||
where
|
||||
T: TryFrom<u64> + TryFrom<i64> + FromStr,
|
||||
<T as TryFrom<u64>>::Error: Display,
|
||||
<T as TryFrom<i64>>::Error: Display,
|
||||
<T as FromStr>::Err: Display,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("an integer or string")
|
||||
}
|
||||
|
||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
T::try_from(v).map_err(serde::de::Error::custom)
|
||||
}
|
||||
|
||||
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
T::try_from(v).map_err(serde::de::Error::custom)
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
v.parse().map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result<T, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
T: TryFrom<u64> + TryFrom<i64> + FromStr,
|
||||
<T as TryFrom<u64>>::Error: Display,
|
||||
<T as TryFrom<i64>>::Error: Display,
|
||||
<T as FromStr>::Err: Display,
|
||||
{
|
||||
deserializer.deserialize_any(NumberVisitor {
|
||||
marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Struct {
|
||||
#[serde(deserialize_with = "deserialize_integer_or_string")]
|
||||
pub i: i64,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let j = r#" {"i":100} "#;
|
||||
println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
|
||||
|
||||
let j = r#" {"i":"100"} "#;
|
||||
println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
|
||||
}
|
9
vendor/serde_json/tests/regression/issue953.rs
vendored
Normal file
9
vendor/serde_json/tests/regression/issue953.rs
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
use serde_json::Value;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let x1 = serde_json::from_str::<Value>("18446744073709551615.");
|
||||
assert!(x1.is_err());
|
||||
let x2 = serde_json::from_str::<Value>("18446744073709551616.");
|
||||
assert!(x2.is_err());
|
||||
}
|
183
vendor/serde_json/tests/stream.rs
vendored
Normal file
183
vendor/serde_json/tests/stream.rs
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
#![cfg(not(feature = "preserve_order"))]
|
||||
#![allow(clippy::assertions_on_result_states)]
|
||||
|
||||
use serde_json::{json, Deserializer, Value};
|
||||
|
||||
// Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740
|
||||
#[rustfmt::skip]
|
||||
macro_rules! test_stream {
|
||||
($data:expr, $ty:ty, |$stream:ident| $test:block) => {
|
||||
{
|
||||
let de = Deserializer::from_str($data);
|
||||
let mut $stream = de.into_iter::<$ty>();
|
||||
assert_eq!($stream.byte_offset(), 0);
|
||||
$test
|
||||
}
|
||||
{
|
||||
let de = Deserializer::from_slice($data.as_bytes());
|
||||
let mut $stream = de.into_iter::<$ty>();
|
||||
assert_eq!($stream.byte_offset(), 0);
|
||||
$test
|
||||
}
|
||||
{
|
||||
let mut bytes = $data.as_bytes();
|
||||
let de = Deserializer::from_reader(&mut bytes);
|
||||
let mut $stream = de.into_iter::<$ty>();
|
||||
assert_eq!($stream.byte_offset(), 0);
|
||||
$test
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_newlines() {
|
||||
let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 39);
|
||||
assert_eq!(stream.byte_offset(), 8);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 40);
|
||||
assert_eq!(stream.byte_offset(), 17);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 41);
|
||||
assert_eq!(stream.byte_offset(), 25);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 42);
|
||||
assert_eq!(stream.byte_offset(), 34);
|
||||
|
||||
assert!(stream.next().is_none());
|
||||
assert_eq!(stream.byte_offset(), 34);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_trailing_whitespaces() {
|
||||
let data = "{\"x\":42} \t\n";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 42);
|
||||
assert_eq!(stream.byte_offset(), 8);
|
||||
|
||||
assert!(stream.next().is_none());
|
||||
assert_eq!(stream.byte_offset(), 11);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_truncated() {
|
||||
let data = "{\"x\":40}\n{\"x\":";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert_eq!(stream.next().unwrap().unwrap()["x"], 40);
|
||||
assert_eq!(stream.byte_offset(), 8);
|
||||
|
||||
assert!(stream.next().unwrap().unwrap_err().is_eof());
|
||||
assert_eq!(stream.byte_offset(), 9);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_truncated_decimal() {
|
||||
let data = "{\"x\":4.";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert!(stream.next().unwrap().unwrap_err().is_eof());
|
||||
assert_eq!(stream.byte_offset(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_truncated_negative() {
|
||||
let data = "{\"x\":-";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert!(stream.next().unwrap().unwrap_err().is_eof());
|
||||
assert_eq!(stream.byte_offset(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_truncated_exponent() {
|
||||
let data = "{\"x\":4e";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert!(stream.next().unwrap().unwrap_err().is_eof());
|
||||
assert_eq!(stream.byte_offset(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_empty() {
|
||||
let data = "";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert!(stream.next().is_none());
|
||||
assert_eq!(stream.byte_offset(), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_primitive() {
|
||||
let data = "{} true{}1[]\nfalse\"hey\"2 ";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert_eq!(stream.next().unwrap().unwrap(), json!({}));
|
||||
assert_eq!(stream.byte_offset(), 2);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), true);
|
||||
assert_eq!(stream.byte_offset(), 7);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), json!({}));
|
||||
assert_eq!(stream.byte_offset(), 9);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), 1);
|
||||
assert_eq!(stream.byte_offset(), 10);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), json!([]));
|
||||
assert_eq!(stream.byte_offset(), 12);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), false);
|
||||
assert_eq!(stream.byte_offset(), 18);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), "hey");
|
||||
assert_eq!(stream.byte_offset(), 23);
|
||||
|
||||
assert_eq!(stream.next().unwrap().unwrap(), 2);
|
||||
assert_eq!(stream.byte_offset(), 24);
|
||||
|
||||
assert!(stream.next().is_none());
|
||||
assert_eq!(stream.byte_offset(), 25);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_invalid_literal() {
|
||||
let data = "truefalse";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
let second = stream.next().unwrap().unwrap_err();
|
||||
assert_eq!(second.to_string(), "trailing characters at line 1 column 5");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_json_stream_invalid_number() {
|
||||
let data = "1true";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
let second = stream.next().unwrap().unwrap_err();
|
||||
assert_eq!(second.to_string(), "trailing characters at line 1 column 2");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error() {
|
||||
let data = "true wrong false";
|
||||
|
||||
test_stream!(data, Value, |stream| {
|
||||
assert_eq!(stream.next().unwrap().unwrap(), true);
|
||||
assert!(stream.next().unwrap().is_err());
|
||||
assert!(stream.next().is_none());
|
||||
});
|
||||
}
|
2505
vendor/serde_json/tests/test.rs
vendored
Normal file
2505
vendor/serde_json/tests/test.rs
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
vendor/serde_json/tests/ui/missing_colon.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/missing_colon.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "a" });
|
||||
}
|
12
vendor/serde_json/tests/ui/missing_colon.stderr
vendored
Normal file
12
vendor/serde_json/tests/ui/missing_colon.stderr
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
error: unexpected end of macro invocation
|
||||
--> tests/ui/missing_colon.rs:4:5
|
||||
|
|
||||
4 | json!({ "a" });
|
||||
| ^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `@`
|
||||
--> src/macros.rs
|
||||
|
|
||||
| (@array [$($elems:expr,)*]) => {
|
||||
| ^
|
||||
= note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
|
5
vendor/serde_json/tests/ui/missing_comma.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/missing_comma.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "1": "" "2": "" });
|
||||
}
|
13
vendor/serde_json/tests/ui/missing_comma.stderr
vendored
Normal file
13
vendor/serde_json/tests/ui/missing_comma.stderr
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
error: no rules expected the token `"2"`
|
||||
--> tests/ui/missing_comma.rs:4:21
|
||||
|
|
||||
4 | json!({ "1": "" "2": "" });
|
||||
| -^^^ no rules expected this token in macro call
|
||||
| |
|
||||
| help: missing comma here
|
||||
|
|
||||
note: while trying to match `,`
|
||||
--> src/macros.rs
|
||||
|
|
||||
| ($e:expr , $($tt:tt)*) => {};
|
||||
| ^
|
5
vendor/serde_json/tests/ui/missing_value.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/missing_value.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "a" : });
|
||||
}
|
12
vendor/serde_json/tests/ui/missing_value.stderr
vendored
Normal file
12
vendor/serde_json/tests/ui/missing_value.stderr
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
error: unexpected end of macro invocation
|
||||
--> tests/ui/missing_value.rs:4:5
|
||||
|
|
||||
4 | json!({ "a" : });
|
||||
| ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
|
||||
|
|
||||
note: while trying to match `@`
|
||||
--> src/macros.rs
|
||||
|
|
||||
| (@array [$($elems:expr,)*]) => {
|
||||
| ^
|
||||
= note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
|
5
vendor/serde_json/tests/ui/not_found.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/not_found.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "a" : x });
|
||||
}
|
5
vendor/serde_json/tests/ui/not_found.stderr
vendored
Normal file
5
vendor/serde_json/tests/ui/not_found.stderr
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
error[E0425]: cannot find value `x` in this scope
|
||||
--> tests/ui/not_found.rs:4:19
|
||||
|
|
||||
4 | json!({ "a" : x });
|
||||
| ^ not found in this scope
|
5
vendor/serde_json/tests/ui/parse_expr.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/parse_expr.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "a" : ~ });
|
||||
}
|
11
vendor/serde_json/tests/ui/parse_expr.stderr
vendored
Normal file
11
vendor/serde_json/tests/ui/parse_expr.stderr
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
error: no rules expected the token `~`
|
||||
--> tests/ui/parse_expr.rs:4:19
|
||||
|
|
||||
4 | json!({ "a" : ~ });
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
note: while trying to match meta-variable `$e:expr`
|
||||
--> src/macros.rs
|
||||
|
|
||||
| ($e:expr , $($tt:tt)*) => {};
|
||||
| ^^^^^^^
|
5
vendor/serde_json/tests/ui/parse_key.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/parse_key.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "".s : true });
|
||||
}
|
5
vendor/serde_json/tests/ui/parse_key.stderr
vendored
Normal file
5
vendor/serde_json/tests/ui/parse_key.stderr
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
error[E0609]: no field `s` on type `&'static str`
|
||||
--> tests/ui/parse_key.rs:4:16
|
||||
|
|
||||
4 | json!({ "".s : true });
|
||||
| ^ unknown field
|
5
vendor/serde_json/tests/ui/unexpected_after_array_element.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/unexpected_after_array_element.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!([ true => ]);
|
||||
}
|
7
vendor/serde_json/tests/ui/unexpected_after_array_element.stderr
vendored
Normal file
7
vendor/serde_json/tests/ui/unexpected_after_array_element.stderr
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
error: no rules expected the token `=>`
|
||||
--> tests/ui/unexpected_after_array_element.rs:4:18
|
||||
|
|
||||
4 | json!([ true => ]);
|
||||
| ^^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
5
vendor/serde_json/tests/ui/unexpected_after_map_entry.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/unexpected_after_map_entry.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "k": true => });
|
||||
}
|
7
vendor/serde_json/tests/ui/unexpected_after_map_entry.stderr
vendored
Normal file
7
vendor/serde_json/tests/ui/unexpected_after_map_entry.stderr
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
error: no rules expected the token `=>`
|
||||
--> tests/ui/unexpected_after_map_entry.rs:4:23
|
||||
|
|
||||
4 | json!({ "k": true => });
|
||||
| ^^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
5
vendor/serde_json/tests/ui/unexpected_colon.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/unexpected_colon.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ : true });
|
||||
}
|
7
vendor/serde_json/tests/ui/unexpected_colon.stderr
vendored
Normal file
7
vendor/serde_json/tests/ui/unexpected_colon.stderr
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
error: no rules expected the token `:`
|
||||
--> tests/ui/unexpected_colon.rs:4:13
|
||||
|
|
||||
4 | json!({ : true });
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
5
vendor/serde_json/tests/ui/unexpected_comma.rs
vendored
Normal file
5
vendor/serde_json/tests/ui/unexpected_comma.rs
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
use serde_json::json;
|
||||
|
||||
fn main() {
|
||||
json!({ "a" , "b": true });
|
||||
}
|
7
vendor/serde_json/tests/ui/unexpected_comma.stderr
vendored
Normal file
7
vendor/serde_json/tests/ui/unexpected_comma.stderr
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
error: no rules expected the token `,`
|
||||
--> tests/ui/unexpected_comma.rs:4:17
|
||||
|
|
||||
4 | json!({ "a" , "b": true });
|
||||
| ^ no rules expected this token in macro call
|
||||
|
|
||||
= note: while trying to match end of macro
|
Reference in New Issue
Block a user