From a16730c92c63c201d220cbf6cb5577a915d3d2b6 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Wed, 22 Aug 2018 10:28:40 +0200 Subject: [PATCH] Bug 1396821 - Update vendored Rust crates. r=ato MozReview-Commit-ID: D8W2mtdAmpb --HG-- rename : third_party/rust/rustc-serialize/LICENSE-APACHE => third_party/rust/serde_json/LICENSE-APACHE rename : third_party/rust/rustc-serialize/LICENSE-MIT => third_party/rust/serde_json/LICENSE-MIT extra : rebase_source : ca3b49695926adb5ec2ae0eb4cdfd4335a740467 --- Cargo.lock | 34 +- .../rust/rustc-serialize/.cargo-checksum.json | 1 - third_party/rust/rustc-serialize/.travis.yml | 24 - third_party/rust/rustc-serialize/Cargo.toml | 18 - third_party/rust/rustc-serialize/README.md | 31 - third_party/rust/rustc-serialize/appveyor.yml | 17 - .../rust/rustc-serialize/benches/base64.rs | 48 - .../rust/rustc-serialize/benches/hex.rs | 28 - .../rust/rustc-serialize/benches/json.rs | 84 - .../rust/rustc-serialize/src/base64.rs | 489 -- .../rustc-serialize/src/collection_impls.rs | 186 - third_party/rust/rustc-serialize/src/hex.rs | 221 - third_party/rust/rustc-serialize/src/json.rs | 3999 ----------------- third_party/rust/rustc-serialize/src/lib.rs | 79 - .../rust/rustc-serialize/src/serialize.rs | 1671 ------- third_party/rust/ryu/.cargo-checksum.json | 1 + third_party/rust/ryu/.travis.yml | 13 + third_party/rust/ryu/Cargo.toml | 39 + third_party/rust/ryu/LICENSE-APACHE | 201 + third_party/rust/ryu/README.md | 74 + third_party/rust/ryu/benchmark/benchmark.rs | 86 + third_party/rust/ryu/build.rs | 54 + third_party/rust/ryu/src/buffer/mod.rs | 97 + third_party/rust/ryu/src/common.rs | 72 + third_party/rust/ryu/src/d2s.rs | 553 +++ third_party/rust/ryu/src/d2s_full_table.rs | 643 +++ third_party/rust/ryu/src/d2s_small_table.rs | 206 + third_party/rust/ryu/src/digit_table.rs | 28 + third_party/rust/ryu/src/f2s.rs | 494 ++ third_party/rust/ryu/src/lib.rs | 68 + third_party/rust/ryu/src/mulshift128.rs | 57 + third_party/rust/ryu/src/pretty/exponent.rs | 49 + third_party/rust/ryu/src/pretty/mantissa.rs | 51 + third_party/rust/ryu/src/pretty/mod.rs | 154 + third_party/rust/ryu/tests/d2s_table_test.rs | 52 + third_party/rust/ryu/tests/d2s_test.rs | 154 + third_party/rust/ryu/tests/exhaustive.rs | 55 + third_party/rust/ryu/tests/f2s_test.rs | 183 + third_party/rust/ryu/tests/macros/mod.rs | 12 + .../rust/serde_json/.cargo-checksum.json | 1 + third_party/rust/serde_json/Cargo.toml | 54 + .../LICENSE-APACHE | 0 .../LICENSE-MIT | 0 third_party/rust/serde_json/README.md | 365 ++ third_party/rust/serde_json/src/de.rs | 2265 ++++++++++ third_party/rust/serde_json/src/error.rs | 429 ++ third_party/rust/serde_json/src/iter.rs | 78 + third_party/rust/serde_json/src/lib.rs | 391 ++ third_party/rust/serde_json/src/macros.rs | 309 ++ third_party/rust/serde_json/src/map.rs | 852 ++++ third_party/rust/serde_json/src/number.rs | 770 ++++ third_party/rust/serde_json/src/read.rs | 677 +++ third_party/rust/serde_json/src/ser.rs | 2096 +++++++++ third_party/rust/serde_json/src/value/de.rs | 1376 ++++++ third_party/rust/serde_json/src/value/from.rs | 266 ++ .../rust/serde_json/src/value/index.rs | 274 ++ third_party/rust/serde_json/src/value/mod.rs | 1126 +++++ .../rust/serde_json/src/value/partial_eq.rs | 102 + third_party/rust/serde_json/src/value/ser.rs | 827 ++++ 59 files changed, 15680 insertions(+), 6904 deletions(-) delete mode 100644 third_party/rust/rustc-serialize/.cargo-checksum.json delete mode 100644 third_party/rust/rustc-serialize/.travis.yml delete mode 100644 third_party/rust/rustc-serialize/Cargo.toml delete mode 100644 third_party/rust/rustc-serialize/README.md delete mode 100644 third_party/rust/rustc-serialize/appveyor.yml delete mode 100644 third_party/rust/rustc-serialize/benches/base64.rs delete mode 100644 third_party/rust/rustc-serialize/benches/hex.rs delete mode 100644 third_party/rust/rustc-serialize/benches/json.rs delete mode 100644 third_party/rust/rustc-serialize/src/base64.rs delete mode 100644 third_party/rust/rustc-serialize/src/collection_impls.rs delete mode 100644 third_party/rust/rustc-serialize/src/hex.rs delete mode 100644 third_party/rust/rustc-serialize/src/json.rs delete mode 100644 third_party/rust/rustc-serialize/src/lib.rs delete mode 100644 third_party/rust/rustc-serialize/src/serialize.rs create mode 100644 third_party/rust/ryu/.cargo-checksum.json create mode 100644 third_party/rust/ryu/.travis.yml create mode 100644 third_party/rust/ryu/Cargo.toml create mode 100644 third_party/rust/ryu/LICENSE-APACHE create mode 100644 third_party/rust/ryu/README.md create mode 100644 third_party/rust/ryu/benchmark/benchmark.rs create mode 100644 third_party/rust/ryu/build.rs create mode 100644 third_party/rust/ryu/src/buffer/mod.rs create mode 100644 third_party/rust/ryu/src/common.rs create mode 100644 third_party/rust/ryu/src/d2s.rs create mode 100644 third_party/rust/ryu/src/d2s_full_table.rs create mode 100644 third_party/rust/ryu/src/d2s_small_table.rs create mode 100644 third_party/rust/ryu/src/digit_table.rs create mode 100644 third_party/rust/ryu/src/f2s.rs create mode 100644 third_party/rust/ryu/src/lib.rs create mode 100644 third_party/rust/ryu/src/mulshift128.rs create mode 100644 third_party/rust/ryu/src/pretty/exponent.rs create mode 100644 third_party/rust/ryu/src/pretty/mantissa.rs create mode 100644 third_party/rust/ryu/src/pretty/mod.rs create mode 100644 third_party/rust/ryu/tests/d2s_table_test.rs create mode 100644 third_party/rust/ryu/tests/d2s_test.rs create mode 100644 third_party/rust/ryu/tests/exhaustive.rs create mode 100644 third_party/rust/ryu/tests/f2s_test.rs create mode 100644 third_party/rust/ryu/tests/macros/mod.rs create mode 100644 third_party/rust/serde_json/.cargo-checksum.json create mode 100644 third_party/rust/serde_json/Cargo.toml rename third_party/rust/{rustc-serialize => serde_json}/LICENSE-APACHE (100%) rename third_party/rust/{rustc-serialize => serde_json}/LICENSE-MIT (100%) create mode 100644 third_party/rust/serde_json/README.md create mode 100644 third_party/rust/serde_json/src/de.rs create mode 100644 third_party/rust/serde_json/src/error.rs create mode 100644 third_party/rust/serde_json/src/iter.rs create mode 100644 third_party/rust/serde_json/src/lib.rs create mode 100644 third_party/rust/serde_json/src/macros.rs create mode 100644 third_party/rust/serde_json/src/map.rs create mode 100644 third_party/rust/serde_json/src/number.rs create mode 100644 third_party/rust/serde_json/src/read.rs create mode 100644 third_party/rust/serde_json/src/ser.rs create mode 100644 third_party/rust/serde_json/src/value/de.rs create mode 100644 third_party/rust/serde_json/src/value/from.rs create mode 100644 third_party/rust/serde_json/src/value/index.rs create mode 100644 third_party/rust/serde_json/src/value/mod.rs create mode 100644 third_party/rust/serde_json/src/value/partial_eq.rs create mode 100644 third_party/rust/serde_json/src/value/ser.rs diff --git a/Cargo.lock b/Cargo.lock index 8c24727e932d..cec05e5f2680 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -806,6 +806,7 @@ dependencies = [ name = "geckodriver" version = "0.21.0" dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -815,7 +816,9 @@ dependencies = [ "mozrunner 0.7.0", "mozversion 0.1.3", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "webdriver 0.36.0", "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1837,11 +1840,6 @@ name = "rustc-demangle" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rustc_version" version = "0.2.1" @@ -1850,6 +1848,11 @@ dependencies = [ "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ryu" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "safemem" version = "0.2.0" @@ -1929,6 +1932,16 @@ dependencies = [ "syn 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_json" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "servo_arc" version = "0.1.1" @@ -2414,11 +2427,15 @@ dependencies = [ name = "webdriver" version = "0.36.0" dependencies = [ + "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2797,8 +2814,8 @@ dependencies = [ "checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd" "checksum rust-ini 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a654c5bda722c699be6b0fe4c0d90de218928da5b724c3e467fc48865c37263" "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" +"checksum ryu 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0568787116e13c652377b6846f5931454a363a8fdf8ae50463ee40935b278b" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" @@ -2808,6 +2825,7 @@ dependencies = [ "checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95" "checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3" "checksum serde_derive 1.0.66 (git+https://github.com/servo/serde?branch=deserialize_from_enums8)" = "" +"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" "checksum simd 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3686dd9418ebcc3a26a0c0ae56deab0681e53fe899af91f5bbcee667ebffb1" "checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" diff --git a/third_party/rust/rustc-serialize/.cargo-checksum.json b/third_party/rust/rustc-serialize/.cargo-checksum.json deleted file mode 100644 index dd0d0b952765..000000000000 --- a/third_party/rust/rustc-serialize/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{".travis.yml":"03dcea6dcd54625b42d91176e86718626dfd911744a343dee3edefa001e87dc5","Cargo.toml":"01199fa6ca6337a7513e9ef8951268b8882347e5affaa50e710ac4960d9c65e0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"0aebc3beb6fc32d6073582d5fea170761689a2c83cddb5436aa26e57b7d04e7b","appveyor.yml":"da991211b72fa6f231af7adb84c9fb72f5a9131d1c0a3d47b8ceffe5a82c8542","benches/base64.rs":"96f7d0c7d260362e41b8cefb4839f1e1b3c18c2f10344f6ccafac7c434f99ca9","benches/hex.rs":"057821307b4b7de02f2c267f9248457386035382916c5afe4b72d6f2e905062c","benches/json.rs":"659f2ae2e1ad5ed022fafce6418d17dfe09c3dcb3f054857dce0effc907da850","src/base64.rs":"57649c590c1fba643ff955910f1d4427feda43414bb0863cd279bea56c3ff178","src/collection_impls.rs":"8ae6bc0d61a4777d834c2b24fa987550cb13c570e1564f87ee32eceff3cb2d5b","src/hex.rs":"a2ba86cf47035b5d9cbf4adf8dc3e941d4e0a6ce1a61a29cbb14ea1fdabac6bb","src/json.rs":"75a788a46612c73bfd14af20fb48855dc8c930747c5255a288d2d09de25ea960","src/lib.rs":"a0e4a368a609f019434e7584f54448cf33ebf3e37e3fb1dd5537d300088184b1","src/serialize.rs":"7ddcc3c32843850e30d05b82a8cda8ae63ec0016e2b0bfbcc46a03ea3ea986e8"},"package":"dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"} \ No newline at end of file diff --git a/third_party/rust/rustc-serialize/.travis.yml b/third_party/rust/rustc-serialize/.travis.yml deleted file mode 100644 index 62bd8391dca9..000000000000 --- a/third_party/rust/rustc-serialize/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: rust -rust: - - 1.0.0 - - stable - - beta - - nightly -sudo: false -before_script: - - pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH -script: - - cargo build --verbose - - cargo test --verbose - - cargo doc --no-deps -after_success: - - travis-cargo --only nightly doc-upload -env: - global: - secure: "kJnqqAXRl0C7Afx0c8Y3vA6TAEZsxlasu7eIZMdCbNS4N1+Rwh0jNTa2jy2D3CQCrzW5OCefnkpkPTu8mADrAjedM4p/9X5UXZi0sgg2lzCgfGwrRzitTnyPDkdYidiu4QeC/r0WPC8lYZKHkJXYhF8bZgchB9ypnZ6LAHCcDkA=" - - - -notifications: - email: - on_success: never diff --git a/third_party/rust/rustc-serialize/Cargo.toml b/third_party/rust/rustc-serialize/Cargo.toml deleted file mode 100644 index 2f44e0c5d051..000000000000 --- a/third_party/rust/rustc-serialize/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] - -name = "rustc-serialize" -version = "0.3.24" -authors = ["The Rust Project Developers"] -license = "MIT/Apache-2.0" -readme = "README.md" -repository = "https://github.com/rust-lang/rustc-serialize" -homepage = "https://github.com/rust-lang/rustc-serialize" -documentation = "https://doc.rust-lang.org/rustc-serialize" -description = """ -Generic serialization/deserialization support corresponding to the -`derive(RustcEncodable, RustcDecodable)` mode in the compiler. Also includes -support for hex, base64, and json encoding and decoding. -""" - -[dev-dependencies] -rand = "0.3" diff --git a/third_party/rust/rustc-serialize/README.md b/third_party/rust/rustc-serialize/README.md deleted file mode 100644 index f680842afc50..000000000000 --- a/third_party/rust/rustc-serialize/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# rustc-serialize - -> **NOTE**: This crate is deprecated in favor of [`serde`]. No new feature -> development will happen in this crate, although bug fixes proposed through PRs -> will still be merged. It is very highly recommended by the Rust Library Team -> that you use [`serde`], not this crate. - -[`serde`]: https://serde.rs - -Serialization and deserialization support provided by the compiler in the form -of `derive(RustcEncodable, RustcDecodable)`. - -[![Linux Build Status](https://travis-ci.org/rust-lang-nursery/rustc-serialize.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/rustc-serialize) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/ka194de75aapwpft?svg=true)](https://ci.appveyor.com/project/alexcrichton/rustc-serialize) - -[Documentation](https://doc.rust-lang.org/rustc-serialize) - -## Usage - -Add this to your `Cargo.toml`: - -```toml -[dependencies] -rustc-serialize = "0.3" -``` - -and this to your crate root: - -```rust -extern crate rustc_serialize; -``` diff --git a/third_party/rust/rustc-serialize/appveyor.yml b/third_party/rust/rustc-serialize/appveyor.yml deleted file mode 100644 index 6a1b8dc19c03..000000000000 --- a/third_party/rust/rustc-serialize/appveyor.yml +++ /dev/null @@ -1,17 +0,0 @@ -environment: - matrix: - - TARGET: x86_64-pc-windows-msvc - - TARGET: i686-pc-windows-msvc - - TARGET: i686-pc-windows-gnu -install: - - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe" - - rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" - - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin - - SET PATH=%PATH%;C:\MinGW\bin - - rustc -V - - cargo -V - -build: false - -test_script: - - cargo test --verbose diff --git a/third_party/rust/rustc-serialize/benches/base64.rs b/third_party/rust/rustc-serialize/benches/base64.rs deleted file mode 100644 index 6a6565bc1482..000000000000 --- a/third_party/rust/rustc-serialize/benches/base64.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![feature(test)] - -extern crate test; -extern crate rustc_serialize; - -use rustc_serialize::base64::{FromBase64, ToBase64, STANDARD}; -use test::Bencher; - -#[bench] -fn bench_to_base64(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - b.iter(|| { - s.as_bytes().to_base64(STANDARD); - }); - b.bytes = s.len() as u64; -} - -#[bench] -fn bench_from_base64(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - let sb = s.as_bytes().to_base64(STANDARD); - b.iter(|| { - sb.from_base64().unwrap(); - }); - b.bytes = sb.len() as u64; -} - - -#[bench] -fn bench_to_base64_large(b: &mut Bencher) { - let s: Vec<_> = (0..10000).map(|i| ((i as u32 * 12345) % 256) as u8).collect(); - b.iter(|| { - s.to_base64(STANDARD); - }); - b.bytes = s.len() as u64; -} - -#[bench] -fn bench_from_base64_large(b: &mut Bencher) { - let s: Vec<_> = (0..10000).map(|i| ((i as u32 * 12345) % 256) as u8).collect(); - let sb = s.to_base64(STANDARD); - b.iter(|| { - sb.from_base64().unwrap(); - }); - b.bytes = sb.len() as u64; -} diff --git a/third_party/rust/rustc-serialize/benches/hex.rs b/third_party/rust/rustc-serialize/benches/hex.rs deleted file mode 100644 index 97a7735e8175..000000000000 --- a/third_party/rust/rustc-serialize/benches/hex.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(test)] - -extern crate test; -extern crate rustc_serialize; - -use test::Bencher; -use rustc_serialize::hex::{FromHex, ToHex}; - -#[bench] -fn bench_to_hex(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - b.iter(|| { - s.as_bytes().to_hex(); - }); - b.bytes = s.len() as u64; -} - -#[bench] -fn bench_from_hex(b: &mut Bencher) { - let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \ - ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン"; - let sb = s.as_bytes().to_hex(); - b.iter(|| { - sb.from_hex().unwrap(); - }); - b.bytes = sb.len() as u64; -} diff --git a/third_party/rust/rustc-serialize/benches/json.rs b/third_party/rust/rustc-serialize/benches/json.rs deleted file mode 100644 index 20768e116a7c..000000000000 --- a/third_party/rust/rustc-serialize/benches/json.rs +++ /dev/null @@ -1,84 +0,0 @@ -#![feature(test)] - -extern crate test; -extern crate rustc_serialize; - -use std::string; -use rustc_serialize::json::{Json, Parser}; -use test::Bencher; - -#[bench] -fn bench_streaming_small(b: &mut Bencher) { - b.iter( || { - let mut parser = Parser::new( - r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} } - ] - }"#.chars() - ); - loop { - match parser.next() { - None => return, - _ => {} - } - } - }); -} -#[bench] -fn bench_small(b: &mut Bencher) { - b.iter( || { - let _ = Json::from_str(r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} } - ] - }"#); - }); -} - -#[bench] -fn bench_decode_hex_escape(b: &mut Bencher) { - let mut src = "\"".to_string(); - for _ in 0..10 { - src.push_str("\\uF975\\uf9bc\\uF9A0\\uF9C4\\uF975\\uf9bc\\uF9A0\\uF9C4"); - } - src.push_str("\""); - b.iter( || { - let _ = Json::from_str(&src); - }); -} - -fn big_json() -> string::String { - let mut src = "[\n".to_string(); - for _ in 0..500 { - src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": \ - [1,2,3]},"#); - } - src.push_str("{}]"); - return src; -} - -#[bench] -fn bench_streaming_large(b: &mut Bencher) { - let src = big_json(); - b.iter( || { - let mut parser = Parser::new(src.chars()); - loop { - match parser.next() { - None => return, - _ => {} - } - } - }); -} -#[bench] -fn bench_large(b: &mut Bencher) { - let src = big_json(); - b.iter( || { let _ = Json::from_str(&src); }); -} diff --git a/third_party/rust/rustc-serialize/src/base64.rs b/third_party/rust/rustc-serialize/src/base64.rs deleted file mode 100644 index 3c346b8947f9..000000000000 --- a/third_party/rust/rustc-serialize/src/base64.rs +++ /dev/null @@ -1,489 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// ignore-lexer-test FIXME #15679 - -//! Base64 binary-to-text encoding - -pub use self::FromBase64Error::*; -pub use self::CharacterSet::*; - -use std::fmt; -use std::error; - -/// Available encoding character sets -#[derive(Clone, Copy, Debug)] -pub enum CharacterSet { - /// The standard character set (uses `+` and `/`) - Standard, - /// The URL safe character set (uses `-` and `_`) - UrlSafe -} - -/// Available newline types -#[derive(Clone, Copy, Debug)] -pub enum Newline { - /// A linefeed (i.e. Unix-style newline) - LF, - /// A carriage return and a linefeed (i.e. Windows-style newline) - CRLF -} - -/// Contains configuration parameters for `to_base64`. -#[derive(Clone, Copy, Debug)] -pub struct Config { - /// Character set to use - pub char_set: CharacterSet, - /// Newline to use - pub newline: Newline, - /// True to pad output with `=` characters - pub pad: bool, - /// `Some(len)` to wrap lines at `len`, `None` to disable line wrapping - pub line_length: Option -} - -/// Configuration for RFC 4648 standard base64 encoding -pub static STANDARD: Config = - Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: None}; - -/// Configuration for RFC 4648 base64url encoding -pub static URL_SAFE: Config = - Config {char_set: UrlSafe, newline: Newline::CRLF, pad: false, line_length: None}; - -/// Configuration for RFC 2045 MIME base64 encoding -pub static MIME: Config = - Config {char_set: Standard, newline: Newline::CRLF, pad: true, line_length: Some(76)}; - -static STANDARD_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789+/"; - -static URLSAFE_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ - abcdefghijklmnopqrstuvwxyz\ - 0123456789-_"; - -/// A trait for converting a value to base64 encoding. -pub trait ToBase64 { - /// Converts the value of `self` to a base64 value following the specified - /// format configuration, returning the owned string. - fn to_base64(&self, config: Config) -> String; -} - -impl ToBase64 for [u8] { - /// Turn a vector of `u8` bytes into a base64 string. - /// - /// # Example - /// - /// ```rust - /// extern crate rustc_serialize; - /// use rustc_serialize::base64::{ToBase64, STANDARD}; - /// - /// fn main () { - /// let str = [52,32].to_base64(STANDARD); - /// println!("base 64 output: {:?}", str); - /// } - /// ``` - fn to_base64(&self, config: Config) -> String { - let bytes = match config.char_set { - Standard => STANDARD_CHARS, - UrlSafe => URLSAFE_CHARS - }; - - let len = self.len(); - let newline = match config.newline { - Newline::LF => "\n", - Newline::CRLF => "\r\n", - }; - - // Preallocate memory. - let mut prealloc_len = (len + 2) / 3 * 4; - if let Some(line_length) = config.line_length { - let num_lines = match prealloc_len { - 0 => 0, - n => (n - 1) / line_length - }; - prealloc_len += num_lines * newline.bytes().count(); - } - - let mut out_bytes = vec![b'='; prealloc_len]; - - // Deal with padding bytes - let mod_len = len % 3; - - // Use iterators to reduce branching - { - let mut cur_length = 0; - - let mut s_in = self[..len - mod_len].iter().map(|&x| x as u32); - let mut s_out = out_bytes.iter_mut(); - - // Convenient shorthand - let enc = |val| bytes[val as usize]; - let mut write = |val| *s_out.next().unwrap() = val; - - // Iterate though blocks of 4 - while let (Some(first), Some(second), Some(third)) = - (s_in.next(), s_in.next(), s_in.next()) { - - // Line break if needed - if let Some(line_length) = config.line_length { - if cur_length >= line_length { - for b in newline.bytes() { write(b) }; - cur_length = 0; - } - } - - let n = first << 16 | second << 8 | third; - - // This 24-bit number gets separated into four 6-bit numbers. - write(enc((n >> 18) & 63)); - write(enc((n >> 12) & 63)); - write(enc((n >> 6 ) & 63)); - write(enc((n >> 0 ) & 63)); - - cur_length += 4; - } - - // Line break only needed if padding is required - if mod_len != 0 { - if let Some(line_length) = config.line_length { - if cur_length >= line_length { - for b in newline.bytes() { write(b) }; - } - } - } - - // Heh, would be cool if we knew this was exhaustive - // (the dream of bounded integer types) - match mod_len { - 0 => (), - 1 => { - let n = (self[len-1] as u32) << 16; - write(enc((n >> 18) & 63)); - write(enc((n >> 12) & 63)); - } - 2 => { - let n = (self[len-2] as u32) << 16 | - (self[len-1] as u32) << 8; - write(enc((n >> 18) & 63)); - write(enc((n >> 12) & 63)); - write(enc((n >> 6 ) & 63)); - } - _ => panic!("Algebra is broken, please alert the math police") - } - } - - // We get padding for "free", so only have to drop it if unwanted. - if !config.pad { - while let Some(&b'=') = out_bytes.last() { - out_bytes.pop(); - } - } - - unsafe { String::from_utf8_unchecked(out_bytes) } - } -} - -impl<'a, T: ?Sized + ToBase64> ToBase64 for &'a T { - fn to_base64(&self, config: Config) -> String { - (**self).to_base64(config) - } -} - -/// A trait for converting from base64 encoded values. -pub trait FromBase64 { - /// Converts the value of `self`, interpreted as base64 encoded data, into - /// an owned vector of bytes, returning the vector. - fn from_base64(&self) -> Result, FromBase64Error>; -} - -/// Errors that can occur when decoding a base64 encoded string -#[derive(Clone, Copy)] -pub enum FromBase64Error { - /// The input contained a character not part of the base64 format - InvalidBase64Byte(u8, usize), - /// The input had an invalid length - InvalidBase64Length, -} - -impl fmt::Debug for FromBase64Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - InvalidBase64Byte(ch, idx) => - write!(f, "Invalid character '{}' at position {}", ch, idx), - InvalidBase64Length => write!(f, "Invalid length"), - } - } -} - -impl error::Error for FromBase64Error { - fn description(&self) -> &str { - match *self { - InvalidBase64Byte(_, _) => "invalid character", - InvalidBase64Length => "invalid length", - } - } -} - -impl fmt::Display for FromBase64Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } -} - -impl FromBase64 for str { - /// Convert any base64 encoded string (literal, `@`, `&`, or `~`) - /// to the byte values it encodes. - /// - /// You can use the `String::from_utf8` function to turn a `Vec` into a - /// string with characters corresponding to those values. - /// - /// # Example - /// - /// This converts a string literal to base64 and back. - /// - /// ```rust - /// extern crate rustc_serialize; - /// use rustc_serialize::base64::{ToBase64, FromBase64, STANDARD}; - /// - /// fn main () { - /// let hello_str = b"Hello, World".to_base64(STANDARD); - /// println!("base64 output: {}", hello_str); - /// let res = hello_str.from_base64(); - /// if res.is_ok() { - /// let opt_bytes = String::from_utf8(res.unwrap()); - /// if opt_bytes.is_ok() { - /// println!("decoded from base64: {:?}", opt_bytes.unwrap()); - /// } - /// } - /// } - /// ``` - #[inline] - fn from_base64(&self) -> Result, FromBase64Error> { - self.as_bytes().from_base64() - } -} - -impl FromBase64 for [u8] { - fn from_base64(&self) -> Result, FromBase64Error> { - let mut r = Vec::with_capacity(self.len()); - let mut buf: u32 = 0; - let mut modulus = 0; - - let mut it = self.iter(); - for byte in it.by_ref() { - let code = DECODE_TABLE[*byte as usize]; - if code >= SPECIAL_CODES_START { - match code { - NEWLINE_CODE => continue, - EQUALS_CODE => break, - INVALID_CODE => return Err(InvalidBase64Byte( - *byte, (byte as *const _ as usize) - self.as_ptr() as usize)), - _ => unreachable!(), - } - } - buf = (buf | code as u32) << 6; - modulus += 1; - if modulus == 4 { - modulus = 0; - r.push((buf >> 22) as u8); - r.push((buf >> 14) as u8); - r.push((buf >> 6 ) as u8); - } - } - - for byte in it { - match *byte { - b'=' | b'\r' | b'\n' => continue, - _ => return Err(InvalidBase64Byte( - *byte, (byte as *const _ as usize) - self.as_ptr() as usize)), - } - } - - match modulus { - 2 => { - r.push((buf >> 10) as u8); - } - 3 => { - r.push((buf >> 16) as u8); - r.push((buf >> 8 ) as u8); - } - 0 => (), - _ => return Err(InvalidBase64Length), - } - - Ok(r) - } -} - -impl<'a, T: ?Sized + FromBase64> FromBase64 for &'a T { - fn from_base64(&self) -> Result, FromBase64Error> { - (**self).from_base64() - } -} - -/// Base64 decoding lookup table, generated using: -/// -/// ``` -/// let mut ch = 0u8; -/// for ch in 0..255 { -/// let mut ch = ch as u8; -/// let code = match ch { -/// b'A'...b'Z' => ch - 0x41, -/// b'a'...b'z' => ch - 0x47, -/// b'0'...b'9' => ch + 0x04, -/// b'+' | b'-' => 0x3E, -/// b'/' | b'_' => 0x3F, -/// b'=' => 0xFE, -/// b'\r' | b'\n' => 0xFD, -/// _ => 0xFF, -/// }; -/// print!("0x{:02X}, ", code); -/// if ch % 16 == 15 { println!(""); } -/// else if ch == 0xFF { break; } -/// ch += 1; -/// } -/// println!(""); -/// ``` -const DECODE_TABLE: [u8; 256] = [ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0x3E, 0xFF, 0x3F, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, - 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -]; -const INVALID_CODE: u8 = 0xFF; -const EQUALS_CODE: u8 = 0xFE; -const NEWLINE_CODE: u8 = 0xFD; -const SPECIAL_CODES_START: u8 = NEWLINE_CODE; - -#[cfg(test)] -mod tests { - use base64::{Config, Newline, FromBase64, ToBase64, STANDARD, URL_SAFE}; - - #[test] - fn test_to_base64_basic() { - assert_eq!("".as_bytes().to_base64(STANDARD), ""); - assert_eq!("f".as_bytes().to_base64(STANDARD), "Zg=="); - assert_eq!("fo".as_bytes().to_base64(STANDARD), "Zm8="); - assert_eq!("foo".as_bytes().to_base64(STANDARD), "Zm9v"); - assert_eq!("foob".as_bytes().to_base64(STANDARD), "Zm9vYg=="); - assert_eq!("fooba".as_bytes().to_base64(STANDARD), "Zm9vYmE="); - assert_eq!("foobar".as_bytes().to_base64(STANDARD), "Zm9vYmFy"); - } - - #[test] - fn test_to_base64_crlf_line_break() { - assert!(![0; 1000].to_base64(Config {line_length: None, ..STANDARD}) - .contains("\r\n")); - assert_eq!(b"foobar".to_base64(Config {line_length: Some(4), - ..STANDARD}), - "Zm9v\r\nYmFy"); - } - - #[test] - fn test_to_base64_lf_line_break() { - assert!(![0; 1000].to_base64(Config {line_length: None, - newline: Newline::LF, - ..STANDARD}) - .contains("\n")); - assert_eq!(b"foobar".to_base64(Config {line_length: Some(4), - newline: Newline::LF, - ..STANDARD}), - "Zm9v\nYmFy"); - } - - #[test] - fn test_to_base64_padding() { - assert_eq!("f".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zg"); - assert_eq!("fo".as_bytes().to_base64(Config {pad: false, ..STANDARD}), "Zm8"); - } - - #[test] - fn test_to_base64_url_safe() { - assert_eq!([251, 255].to_base64(URL_SAFE), "-_8"); - assert_eq!([251, 255].to_base64(STANDARD), "+/8="); - } - - #[test] - fn test_to_base64_empty_line_length() { - [].to_base64(Config {line_length: Some(72), ..STANDARD}); - } - - #[test] - fn test_from_base64_basic() { - assert_eq!("".from_base64().unwrap(), b""); - assert_eq!("Zg==".from_base64().unwrap(), b"f"); - assert_eq!("Zm8=".from_base64().unwrap(), b"fo"); - assert_eq!("Zm9v".from_base64().unwrap(), b"foo"); - assert_eq!("Zm9vYg==".from_base64().unwrap(), b"foob"); - assert_eq!("Zm9vYmE=".from_base64().unwrap(), b"fooba"); - assert_eq!("Zm9vYmFy".from_base64().unwrap(), b"foobar"); - } - - #[test] - fn test_from_base64_bytes() { - assert_eq!(b"Zm9vYmFy".from_base64().unwrap(), b"foobar"); - } - - #[test] - fn test_from_base64_newlines() { - assert_eq!("Zm9v\r\nYmFy".from_base64().unwrap(), - b"foobar"); - assert_eq!("Zm9vYg==\r\n".from_base64().unwrap(), - b"foob"); - assert_eq!("Zm9v\nYmFy".from_base64().unwrap(), - b"foobar"); - assert_eq!("Zm9vYg==\n".from_base64().unwrap(), - b"foob"); - } - - #[test] - fn test_from_base64_urlsafe() { - assert_eq!("-_8".from_base64().unwrap(), "+/8=".from_base64().unwrap()); - } - - #[test] - fn test_from_base64_invalid_char() { - assert!("Zm$=".from_base64().is_err()); - assert!("Zg==$".from_base64().is_err()); - } - - #[test] - fn test_from_base64_invalid_padding() { - assert!("Z===".from_base64().is_err()); - } - - #[test] - fn test_base64_random() { - use rand::{thread_rng, Rng}; - - for _ in 0..1000 { - let times = thread_rng().gen_range(1, 100); - let v = thread_rng().gen_iter::().take(times) - .collect::>(); - assert_eq!(v.to_base64(STANDARD) - .from_base64() - .unwrap(), - v); - } - } -} diff --git a/third_party/rust/rustc-serialize/src/collection_impls.rs b/third_party/rust/rustc-serialize/src/collection_impls.rs deleted file mode 100644 index f8074c911be7..000000000000 --- a/third_party/rust/rustc-serialize/src/collection_impls.rs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Implementations of serialization for structures found in libcollections - -use std::hash::Hash; - -use {Decodable, Encodable, Decoder, Encoder, cap_capacity}; -use std::collections::{LinkedList, VecDeque, BTreeMap, BTreeSet, HashMap, HashSet}; - -impl< - T: Encodable -> Encodable for LinkedList { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - try!(s.emit_seq_elt(i, |s| e.encode(s))); - } - Ok(()) - }) - } -} - -impl Decodable for LinkedList { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_seq(|d, len| { - let mut list = LinkedList::new(); - for i in 0..len { - list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(list) - }) - } -} - -impl Encodable for VecDeque { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - try!(s.emit_seq_elt(i, |s| e.encode(s))); - } - Ok(()) - }) - } -} - -impl Decodable for VecDeque { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_seq(|d, len| { - let mut deque: VecDeque = VecDeque::new(); - for i in 0..len { - deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(deque) - }) - } -} - -impl< - K: Encodable + Ord, - V: Encodable -> Encodable for BTreeMap { - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - try!(e.emit_map_elt_key(i, |e| key.encode(e))); - try!(e.emit_map_elt_val(i, |e| val.encode(e))); - i += 1; - } - Ok(()) - }) - } -} - -impl< - K: Decodable + Ord, - V: Decodable -> Decodable for BTreeMap { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_map(|d, len| { - let mut map = BTreeMap::new(); - for i in 0..len { - let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); - let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); - map.insert(key, val); - } - Ok(map) - }) - } -} - -impl< - T: Encodable + Ord -> Encodable for BTreeSet { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - try!(s.emit_seq_elt(i, |s| e.encode(s))); - i += 1; - } - Ok(()) - }) - } -} - -impl< - T: Decodable + Ord -> Decodable for BTreeSet { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_seq(|d, len| { - let mut set = BTreeSet::new(); - for i in 0..len { - set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(set) - }) - } -} - -impl Encodable for HashMap - where K: Encodable + Hash + Eq, - V: Encodable, -{ - fn encode(&self, e: &mut E) -> Result<(), E::Error> { - e.emit_map(self.len(), |e| { - let mut i = 0; - for (key, val) in self.iter() { - try!(e.emit_map_elt_key(i, |e| key.encode(e))); - try!(e.emit_map_elt_val(i, |e| val.encode(e))); - i += 1; - } - Ok(()) - }) - } -} - -impl Decodable for HashMap - where K: Decodable + Hash + Eq, - V: Decodable, -{ - fn decode(d: &mut D) -> Result, D::Error> { - d.read_map(|d, len| { - let mut map = HashMap::with_capacity(cap_capacity::<(K, V)>(len)); - for i in 0..len { - let key = try!(d.read_map_elt_key(i, |d| Decodable::decode(d))); - let val = try!(d.read_map_elt_val(i, |d| Decodable::decode(d))); - map.insert(key, val); - } - Ok(map) - }) - } -} - -impl Encodable for HashSet where T: Encodable + Hash + Eq { - fn encode(&self, s: &mut E) -> Result<(), E::Error> { - s.emit_seq(self.len(), |s| { - let mut i = 0; - for e in self.iter() { - try!(s.emit_seq_elt(i, |s| e.encode(s))); - i += 1; - } - Ok(()) - }) - } -} - -impl Decodable for HashSet where T: Decodable + Hash + Eq, { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_seq(|d, len| { - let mut set = HashSet::with_capacity(cap_capacity::(len)); - for i in 0..len { - set.insert(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(set) - }) - } -} diff --git a/third_party/rust/rustc-serialize/src/hex.rs b/third_party/rust/rustc-serialize/src/hex.rs deleted file mode 100644 index 3c7df19992d9..000000000000 --- a/third_party/rust/rustc-serialize/src/hex.rs +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. -// -// ignore-lexer-test FIXME #15679 - -//! Hex binary-to-text encoding - -pub use self::FromHexError::*; - -use std::fmt; -use std::error; - -/// A trait for converting a value to hexadecimal encoding -pub trait ToHex { - /// Converts the value of `self` to a hex value, returning the owned - /// string. - fn to_hex(&self) -> String; -} - -static CHARS: &'static[u8] = b"0123456789abcdef"; - -impl ToHex for [u8] { - /// Turn a vector of `u8` bytes into a hexadecimal string. - /// - /// # Example - /// - /// ```rust - /// extern crate rustc_serialize; - /// use rustc_serialize::hex::ToHex; - /// - /// fn main () { - /// let str = [52,32].to_hex(); - /// println!("{}", str); - /// } - /// ``` - fn to_hex(&self) -> String { - let mut v = Vec::with_capacity(self.len() * 2); - for &byte in self.iter() { - v.push(CHARS[(byte >> 4) as usize]); - v.push(CHARS[(byte & 0xf) as usize]); - } - - unsafe { - String::from_utf8_unchecked(v) - } - } -} - -impl<'a, T: ?Sized + ToHex> ToHex for &'a T { - fn to_hex(&self) -> String { - (**self).to_hex() - } -} - -/// A trait for converting hexadecimal encoded values -pub trait FromHex { - /// Converts the value of `self`, interpreted as hexadecimal encoded data, - /// into an owned vector of bytes, returning the vector. - fn from_hex(&self) -> Result, FromHexError>; -} - -/// Errors that can occur when decoding a hex encoded string -#[derive(Clone, Copy)] -pub enum FromHexError { - /// The input contained a character not part of the hex format - InvalidHexCharacter(char, usize), - /// The input had an invalid length - InvalidHexLength, -} - -impl fmt::Debug for FromHexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - InvalidHexCharacter(ch, idx) => - write!(f, "Invalid character '{}' at position {}", ch, idx), - InvalidHexLength => write!(f, "Invalid input length"), - } - } -} - -impl error::Error for FromHexError { - fn description(&self) -> &str { - match *self { - InvalidHexCharacter(_, _) => "invalid character", - InvalidHexLength => "invalid length", - } - } -} - -impl fmt::Display for FromHexError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } -} - -impl FromHex for str { - /// Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`) - /// to the byte values it encodes. - /// - /// You can use the `String::from_utf8` function to turn a - /// `Vec` into a string with characters corresponding to those values. - /// - /// # Example - /// - /// This converts a string literal to hexadecimal and back. - /// - /// ```rust - /// extern crate rustc_serialize; - /// use rustc_serialize::hex::{FromHex, ToHex}; - /// - /// fn main () { - /// let hello_str = "Hello, World".as_bytes().to_hex(); - /// println!("{}", hello_str); - /// let bytes = hello_str.from_hex().unwrap(); - /// println!("{:?}", bytes); - /// let result_str = String::from_utf8(bytes).unwrap(); - /// println!("{}", result_str); - /// } - /// ``` - fn from_hex(&self) -> Result, FromHexError> { - // This may be an overestimate if there is any whitespace - let mut b = Vec::with_capacity(self.len() / 2); - let mut modulus = 0; - let mut buf = 0; - - for (idx, byte) in self.bytes().enumerate() { - buf <<= 4; - - match byte { - b'A'...b'F' => buf |= byte - b'A' + 10, - b'a'...b'f' => buf |= byte - b'a' + 10, - b'0'...b'9' => buf |= byte - b'0', - b' '|b'\r'|b'\n'|b'\t' => { - buf >>= 4; - continue - } - _ => { - let ch = self[idx..].chars().next().unwrap(); - return Err(InvalidHexCharacter(ch, idx)) - } - } - - modulus += 1; - if modulus == 2 { - modulus = 0; - b.push(buf); - } - } - - match modulus { - 0 => Ok(b.into_iter().collect()), - _ => Err(InvalidHexLength), - } - } -} - -impl<'a, T: ?Sized + FromHex> FromHex for &'a T { - fn from_hex(&self) -> Result, FromHexError> { - (**self).from_hex() - } -} - -#[cfg(test)] -mod tests { - use hex::{FromHex, ToHex}; - - #[test] - pub fn test_to_hex() { - assert_eq!("foobar".as_bytes().to_hex(), "666f6f626172"); - } - - #[test] - pub fn test_from_hex_okay() { - assert_eq!("666f6f626172".from_hex().unwrap(), - b"foobar"); - assert_eq!("666F6F626172".from_hex().unwrap(), - b"foobar"); - } - - #[test] - pub fn test_from_hex_odd_len() { - assert!("666".from_hex().is_err()); - assert!("66 6".from_hex().is_err()); - } - - #[test] - pub fn test_from_hex_invalid_char() { - assert!("66y6".from_hex().is_err()); - } - - #[test] - pub fn test_from_hex_ignores_whitespace() { - assert_eq!("666f 6f6\r\n26172 ".from_hex().unwrap(), - b"foobar"); - } - - #[test] - pub fn test_to_hex_all_bytes() { - for i in 0..256 { - assert_eq!([i as u8].to_hex(), format!("{:02x}", i)); - } - } - - #[test] - pub fn test_from_hex_all_bytes() { - for i in 0..256 { - let ii: &[u8] = &[i as u8]; - assert_eq!(format!("{:02x}", i).from_hex().unwrap(), - ii); - assert_eq!(format!("{:02X}", i).from_hex().unwrap(), - ii); - } - } -} diff --git a/third_party/rust/rustc-serialize/src/json.rs b/third_party/rust/rustc-serialize/src/json.rs deleted file mode 100644 index e478fe8715e2..000000000000 --- a/third_party/rust/rustc-serialize/src/json.rs +++ /dev/null @@ -1,3999 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Rust JSON serialization library -// Copyright (c) 2011 Google Inc. - -//! JSON parsing and serialization -//! -//! # What is JSON? -//! -//! JSON (JavaScript Object Notation) is a way to write data in Javascript. -//! Like XML, it allows encoding structured data in a text format that can be -//! easily read by humans. Its simple syntax and native compatibility with -//! JavaScript have made it a widely used format. -//! -//! Data types that can be encoded are JavaScript types (see the `Json` enum -//! for more details): -//! -//! * `I64`: equivalent to rust's `i64` -//! * `U64`: equivalent to rust's `u64` -//! * `F64`: equivalent to rust's `f64` -//! * `Boolean`: equivalent to rust's `bool` -//! * `String`: equivalent to rust's `String` -//! * `Array`: equivalent to rust's `Vec`, but also allowing objects of -//! different types in the -//! same array -//! * `Object`: equivalent to rust's `BTreeMap` -//! * `Null` -//! -//! An object is a series of string keys mapping to values, in `"key": value` -//! format. Arrays are enclosed in square brackets ([ ... ]) and objects in -//! curly brackets ({ ... }). A simple JSON document encoding a person, -//! their age, address and phone numbers could look like -//! -//! ```ignore -//! { -//! "FirstName": "John", -//! "LastName": "Doe", -//! "Age": 43, -//! "Address": { -//! "Street": "Downing Street 10", -//! "City": "London", -//! "Country": "Great Britain" -//! }, -//! "PhoneNumbers": [ -//! "+44 1234567", -//! "+44 2345678" -//! ] -//! } -//! ``` -//! -//! # Rust Type-based Encoding and Decoding -//! -//! Rust provides a mechanism for low boilerplate encoding & decoding of values -//! to and from JSON via the serialization API. To be able to encode a piece -//! of data, it must implement the `rustc_serialize::Encodable` trait. To be -//! able to decode a piece of data, it must implement the -//! `rustc_serialize::Decodable` trait. The Rust compiler provides an -//! annotation to automatically generate the code for these traits: -//! `#[derive(RustcDecodable, RustcEncodable)]` -//! -//! The JSON API provides an enum `json::Json` and a trait `ToJson` to encode -//! objects. The `ToJson` trait provides a `to_json` method to convert an -//! object into a `json::Json` value. A `json::Json` value can be encoded as a -//! string or buffer using the functions described above. You can also use the -//! `json::Encoder` object, which implements the `Encoder` trait. -//! -//! When using `ToJson`, the `Encodable` trait implementation is not -//! mandatory. -//! -//! # Examples of use -//! -//! ## Using Autoserialization -//! -//! Create a struct called `TestStruct` and serialize and deserialize it to and -//! from JSON using the serialization API, using the derived serialization code. -//! -//! ```rust -//! extern crate rustc_serialize; -//! use rustc_serialize::json; -//! -//! // Automatically generate `RustcDecodable` and `RustcEncodable` trait -//! // implementations -//! #[derive(RustcDecodable, RustcEncodable)] -//! pub struct TestStruct { -//! data_int: u8, -//! data_str: String, -//! data_vector: Vec, -//! } -//! -//! fn main() { -//! let object = TestStruct { -//! data_int: 1, -//! data_str: "homura".to_string(), -//! data_vector: vec![2,3,4,5], -//! }; -//! -//! // Serialize using `json::encode` -//! let encoded = json::encode(&object).unwrap(); -//! -//! // Deserialize using `json::decode` -//! let decoded: TestStruct = json::decode(&encoded).unwrap(); -//! } -//! ``` -//! -//! ## Using the `ToJson` trait -//! -//! The examples below use the `ToJson` trait to generate the JSON string, -//! which is required for custom mappings. -//! -//! ### Simple example of `ToJson` usage -//! -//! ```rust -//! extern crate rustc_serialize; -//! use rustc_serialize::json::{self, ToJson, Json}; -//! -//! // A custom data structure -//! struct ComplexNum { -//! a: f64, -//! b: f64, -//! } -//! -//! // JSON value representation -//! impl ToJson for ComplexNum { -//! fn to_json(&self) -> Json { -//! Json::String(format!("{}+{}i", self.a, self.b)) -//! } -//! } -//! -//! // Only generate `RustcEncodable` trait implementation -//! #[derive(RustcEncodable)] -//! pub struct ComplexNumRecord { -//! uid: u8, -//! dsc: String, -//! val: Json, -//! } -//! -//! fn main() { -//! let num = ComplexNum { a: 0.0001, b: 12.539 }; -//! let data: String = json::encode(&ComplexNumRecord{ -//! uid: 1, -//! dsc: "test".to_string(), -//! val: num.to_json(), -//! }).unwrap(); -//! println!("data: {}", data); -//! // data: {"uid":1,"dsc":"test","val":"0.0001+12.539i"}; -//! } -//! ``` -//! -//! ### Verbose example of `ToJson` usage -//! -//! ```rust -//! extern crate rustc_serialize; -//! use std::collections::BTreeMap; -//! use rustc_serialize::json::{self, Json, ToJson}; -//! -//! // Only generate `Decodable` trait implementation -//! #[derive(RustcDecodable)] -//! pub struct TestStruct { -//! data_int: u8, -//! data_str: String, -//! data_vector: Vec, -//! } -//! -//! // Specify encoding method manually -//! impl ToJson for TestStruct { -//! fn to_json(&self) -> Json { -//! let mut d = BTreeMap::new(); -//! // All standard types implement `to_json()`, so use it -//! d.insert("data_int".to_string(), self.data_int.to_json()); -//! d.insert("data_str".to_string(), self.data_str.to_json()); -//! d.insert("data_vector".to_string(), self.data_vector.to_json()); -//! Json::Object(d) -//! } -//! } -//! -//! fn main() { -//! // Serialize using `ToJson` -//! let input_data = TestStruct { -//! data_int: 1, -//! data_str: "madoka".to_string(), -//! data_vector: vec![2,3,4,5], -//! }; -//! let json_obj: Json = input_data.to_json(); -//! let json_str: String = json_obj.to_string(); -//! -//! // Deserialize like before -//! let decoded: TestStruct = json::decode(&json_str).unwrap(); -//! } -//! ``` -//! -//! ## Parsing a `str` to `Json` and reading the result -//! -//! ```rust -//! extern crate rustc_serialize; -//! use rustc_serialize::json::Json; -//! -//! fn main() { -//! let data = Json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap(); -//! println!("data: {}", data); -//! // data: {"bar":"baz","foo":13} -//! println!("object? {}", data.is_object()); -//! // object? true -//! -//! let obj = data.as_object().unwrap(); -//! let foo = obj.get("foo").unwrap(); -//! -//! println!("array? {:?}", foo.as_array()); -//! // array? None -//! println!("u64? {:?}", foo.as_u64()); -//! // u64? Some(13u64) -//! -//! for (key, value) in obj.iter() { -//! println!("{}: {}", key, match *value { -//! Json::U64(v) => format!("{} (u64)", v), -//! Json::String(ref v) => format!("{} (string)", v), -//! _ => format!("other") -//! }); -//! } -//! // bar: baz (string) -//! // foo: 13 (u64) -//! } -//! ``` -//! -//! # The status of this library -//! -//! While this library is the standard way of working with JSON in Rust, -//! there is a next-generation library called Serde that's in the works (it's -//! faster, overcomes some design limitations of rustc-serialize and has more -//! features). You might consider using it when starting a new project or -//! evaluating Rust JSON performance. - -use self::JsonEvent::*; -use self::ErrorCode::*; -use self::ParserError::*; -use self::DecoderError::*; -use self::ParserState::*; -use self::InternalStackElement::*; - -use std::collections::{HashMap, BTreeMap}; -use std::error::Error as StdError; -use std::i64; -use std::io::prelude::*; -use std::mem::swap; -use std::ops::Index; -use std::str::FromStr; -use std::string; -use std::{char, f64, fmt, io, str}; - -use Encodable; - -/// Represents a json value -#[derive(Clone, PartialEq, PartialOrd, Debug)] -pub enum Json { - I64(i64), - U64(u64), - F64(f64), - String(string::String), - Boolean(bool), - Array(self::Array), - Object(self::Object), - Null, -} - -pub type Array = Vec; -pub type Object = BTreeMap; - -pub struct PrettyJson<'a> { inner: &'a Json } - -pub struct AsJson<'a, T: 'a> { inner: &'a T } -pub struct AsPrettyJson<'a, T: 'a> { inner: &'a T, indent: Option } - -/// The errors that can arise while parsing a JSON stream. -#[derive(Clone, Copy, PartialEq)] -pub enum ErrorCode { - InvalidSyntax, - InvalidNumber, - EOFWhileParsingObject, - EOFWhileParsingArray, - EOFWhileParsingValue, - EOFWhileParsingString, - KeyMustBeAString, - ExpectedColon, - TrailingCharacters, - TrailingComma, - InvalidEscape, - InvalidUnicodeCodePoint, - LoneLeadingSurrogateInHexEscape, - UnexpectedEndOfHexEscape, - UnrecognizedHex, - NotFourDigit, - ControlCharacterInString, - NotUtf8, -} - -#[derive(Debug)] -pub enum ParserError { - /// msg, line, col - SyntaxError(ErrorCode, usize, usize), - IoError(io::Error), -} - -impl PartialEq for ParserError { - fn eq(&self, other: &ParserError) -> bool { - match (self, other) { - (&SyntaxError(msg0, line0, col0), &SyntaxError(msg1, line1, col1)) => - msg0 == msg1 && line0 == line1 && col0 == col1, - (&IoError(_), _) => false, - (_, &IoError(_)) => false, - } - } -} - -// Builder and Parser have the same errors. -pub type BuilderError = ParserError; - -#[derive(PartialEq, Debug)] -pub enum DecoderError { - ParseError(ParserError), - ExpectedError(string::String, string::String), - MissingFieldError(string::String), - UnknownVariantError(string::String), - ApplicationError(string::String), - EOF, -} - -#[derive(Copy, Debug)] -pub enum EncoderError { - FmtError(fmt::Error), - BadHashmapKey, -} - -impl PartialEq for EncoderError { - fn eq(&self, other: &EncoderError) -> bool { - match (*self, *other) { - (EncoderError::FmtError(_), EncoderError::FmtError(_)) => true, - (EncoderError::BadHashmapKey, EncoderError::BadHashmapKey) => true, - _ => false, - } - } -} - -impl Clone for EncoderError { - fn clone(&self) -> Self { *self } -} - -/// Returns a readable error string for a given error code. -pub fn error_str(error: ErrorCode) -> &'static str { - match error { - InvalidSyntax => "invalid syntax", - InvalidNumber => "invalid number", - EOFWhileParsingObject => "EOF While parsing object", - EOFWhileParsingArray => "EOF While parsing array", - EOFWhileParsingValue => "EOF While parsing value", - EOFWhileParsingString => "EOF While parsing string", - KeyMustBeAString => "key must be a string", - ExpectedColon => "expected `:`", - TrailingCharacters => "trailing characters", - TrailingComma => "trailing comma", - InvalidEscape => "invalid escape", - UnrecognizedHex => "invalid \\u{ esc}ape (unrecognized hex)", - NotFourDigit => "invalid \\u{ esc}ape (not four digits)", - ControlCharacterInString => "unescaped control character in string", - NotUtf8 => "contents not utf-8", - InvalidUnicodeCodePoint => "invalid Unicode code point", - LoneLeadingSurrogateInHexEscape => "lone leading surrogate in hex escape", - UnexpectedEndOfHexEscape => "unexpected end of hex escape", - } -} - -/// Shortcut function to decode a JSON `&str` into an object -pub fn decode(s: &str) -> DecodeResult { - let json = match Json::from_str(s) { - Ok(x) => x, - Err(e) => return Err(ParseError(e)) - }; - - let mut decoder = Decoder::new(json); - ::Decodable::decode(&mut decoder) -} - -/// Shortcut function to encode a `T` into a JSON `String` -pub fn encode(object: &T) -> EncodeResult { - let mut s = String::new(); - { - let mut encoder = Encoder::new(&mut s); - try!(object.encode(&mut encoder)); - } - Ok(s) -} - -impl fmt::Debug for ErrorCode { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - error_str(*self).fmt(f) - } -} - -impl StdError for DecoderError { - fn description(&self) -> &str { "decoder error" } - fn cause(&self) -> Option<&StdError> { - match *self { - DecoderError::ParseError(ref e) => Some(e), - _ => None, - } - } -} - -impl fmt::Display for DecoderError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } -} - -impl From for DecoderError { - fn from(err: ParserError) -> DecoderError { - ParseError(From::from(err)) - } -} - -impl StdError for ParserError { - fn description(&self) -> &str { "failed to parse json" } -} - -impl fmt::Display for ParserError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } -} - -impl From for ParserError { - fn from(err: io::Error) -> ParserError { - IoError(err) - } -} - -impl StdError for EncoderError { - fn description(&self) -> &str { "encoder error" } -} - -impl fmt::Display for EncoderError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self, f) - } -} - -impl From for EncoderError { - fn from(err: fmt::Error) -> EncoderError { EncoderError::FmtError(err) } -} - -pub type EncodeResult = Result; -pub type DecodeResult = Result; - -fn escape_str(wr: &mut fmt::Write, v: &str) -> EncodeResult<()> { - try!(wr.write_str("\"")); - - let mut start = 0; - - for (i, byte) in v.bytes().enumerate() { - let escaped = match byte { - b'"' => "\\\"", - b'\\' => "\\\\", - b'\x00' => "\\u0000", - b'\x01' => "\\u0001", - b'\x02' => "\\u0002", - b'\x03' => "\\u0003", - b'\x04' => "\\u0004", - b'\x05' => "\\u0005", - b'\x06' => "\\u0006", - b'\x07' => "\\u0007", - b'\x08' => "\\b", - b'\t' => "\\t", - b'\n' => "\\n", - b'\x0b' => "\\u000b", - b'\x0c' => "\\f", - b'\r' => "\\r", - b'\x0e' => "\\u000e", - b'\x0f' => "\\u000f", - b'\x10' => "\\u0010", - b'\x11' => "\\u0011", - b'\x12' => "\\u0012", - b'\x13' => "\\u0013", - b'\x14' => "\\u0014", - b'\x15' => "\\u0015", - b'\x16' => "\\u0016", - b'\x17' => "\\u0017", - b'\x18' => "\\u0018", - b'\x19' => "\\u0019", - b'\x1a' => "\\u001a", - b'\x1b' => "\\u001b", - b'\x1c' => "\\u001c", - b'\x1d' => "\\u001d", - b'\x1e' => "\\u001e", - b'\x1f' => "\\u001f", - b'\x7f' => "\\u007f", - _ => { continue; } - }; - - if start < i { - try!(wr.write_str(&v[start..i])); - } - - try!(wr.write_str(escaped)); - - start = i + 1; - } - - if start != v.len() { - try!(wr.write_str(&v[start..])); - } - - try!(wr.write_str("\"")); - Ok(()) -} - -fn escape_char(writer: &mut fmt::Write, v: char) -> EncodeResult<()> { - let mut buf = [0; 4]; - let _ = write!(&mut &mut buf[..], "{}", v); - let buf = unsafe { str::from_utf8_unchecked(&buf[..v.len_utf8()]) }; - escape_str(writer, buf) -} - -fn spaces(wr: &mut fmt::Write, n: u32) -> EncodeResult<()> { - let mut n = n as usize; - const BUF: &'static str = " "; - - while n >= BUF.len() { - try!(wr.write_str(BUF)); - n -= BUF.len(); - } - - if n > 0 { - try!(wr.write_str(&BUF[..n])); - } - Ok(()) -} - -fn fmt_number_or_null(v: f64) -> string::String { - use std::num::FpCategory::{Nan, Infinite}; - - match v.classify() { - Nan | Infinite => "null".to_string(), - _ => { - let s = v.to_string(); - if s.contains(".") {s} else {s + ".0"} - } - } -} - -macro_rules! emit_enquoted_if_mapkey { - ($enc:ident,$e:expr) => { - if $enc.is_emitting_map_key { - try!(write!($enc.writer, "\"{}\"", $e)); - Ok(()) - } else { - try!(write!($enc.writer, "{}", $e)); - Ok(()) - } - } -} - -enum EncodingFormat { - Compact, - Pretty { - curr_indent: u32, - indent: u32 - } -} - -/// A structure for implementing serialization to JSON. -pub struct Encoder<'a> { - writer: &'a mut (fmt::Write+'a), - format : EncodingFormat, - is_emitting_map_key: bool, -} - -impl<'a> Encoder<'a> { - /// Creates a new encoder whose output will be written in human-readable - /// JSON to the specified writer - pub fn new_pretty(writer: &'a mut fmt::Write) -> Encoder<'a> { - Encoder { - writer: writer, - format: EncodingFormat::Pretty { - curr_indent: 0, - indent: 2, - }, - is_emitting_map_key: false, - } - } - - /// Creates a new encoder whose output will be written in compact - /// JSON to the specified writer - pub fn new(writer: &'a mut fmt::Write) -> Encoder<'a> { - Encoder { - writer: writer, - format: EncodingFormat::Compact, - is_emitting_map_key: false, - } - } - - /// Set the number of spaces to indent for each level. - /// This is safe to set during encoding. - pub fn set_indent(&mut self, new_indent: u32) -> Result<(), ()> { - if let EncodingFormat::Pretty{ref mut curr_indent, ref mut indent} = self.format { - // self.indent very well could be 0 so we need to use checked division. - let level = curr_indent.checked_div(*indent).unwrap_or(0); - *indent = new_indent; - *curr_indent = level * *indent; - Ok(()) - } else { - Err(()) - } - } -} - -impl<'a> ::Encoder for Encoder<'a> { - type Error = EncoderError; - - fn emit_nil(&mut self) -> EncodeResult<()> { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - try!(write!(self.writer, "null")); - Ok(()) - } - - fn emit_usize(&mut self, v: usize) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_u64(&mut self, v: u64) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_u32(&mut self, v: u32) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_u16(&mut self, v: u16) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_u8(&mut self, v: u8) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - - fn emit_isize(&mut self, v: isize) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_i64(&mut self, v: i64) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_i32(&mut self, v: i32) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_i16(&mut self, v: i16) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - fn emit_i8(&mut self, v: i8) -> EncodeResult<()> { emit_enquoted_if_mapkey!(self, v) } - - fn emit_bool(&mut self, v: bool) -> EncodeResult<()> { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if v { - try!(write!(self.writer, "true")); - } else { - try!(write!(self.writer, "false")); - } - Ok(()) - } - - fn emit_f64(&mut self, v: f64) -> EncodeResult<()> { - emit_enquoted_if_mapkey!(self, fmt_number_or_null(v)) - } - fn emit_f32(&mut self, v: f32) -> EncodeResult<()> { - self.emit_f64(v as f64) - } - - fn emit_char(&mut self, v: char) -> EncodeResult<()> { - escape_char(self.writer, v) - } - fn emit_str(&mut self, v: &str) -> EncodeResult<()> { - escape_str(self.writer, v) - } - - fn emit_enum(&mut self, _name: &str, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - f(self) - } - - fn emit_enum_variant(&mut self, - name: &str, - _id: usize, - cnt: usize, - f: F) - -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - // enums are encoded as strings or objects - // Bunny => "Bunny" - // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]} - if cnt == 0 { - escape_str(self.writer, name) - } else { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - try!(write!(self.writer, "{{\n")); - *curr_indent += indent; - try!(spaces(self.writer, *curr_indent)); - try!(write!(self.writer, "\"variant\": ")); - try!(escape_str(self.writer, name)); - try!(write!(self.writer, ",\n")); - try!(spaces(self.writer, *curr_indent)); - try!(write!(self.writer, "\"fields\": [\n")); - *curr_indent += indent; - } else { - try!(write!(self.writer, "{{\"variant\":")); - try!(escape_str(self.writer, name)); - try!(write!(self.writer, ",\"fields\":[")); - } - try!(f(self)); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent -= indent; - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, *curr_indent)); - *curr_indent -= indent; - try!(write!(self.writer, "]\n")); - try!(spaces(self.writer, *curr_indent)); - try!(write!(self.writer, "}}")); - } else { - try!(write!(self.writer, "]}}")); - } - Ok(()) - } - } - - fn emit_enum_variant_arg(&mut self, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if idx != 0 { - try!(write!(self.writer, ",")); - if let EncodingFormat::Pretty{..} = self.format { - try!(write!(self.writer, "\n")); - } - } - if let EncodingFormat::Pretty{curr_indent, ..} = self.format { - try!(spaces(self.writer, curr_indent)); - } - f(self) - } - - fn emit_enum_struct_variant(&mut self, - name: &str, - id: usize, - cnt: usize, - f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_enum_variant(name, id, cnt, f) - } - - fn emit_enum_struct_variant_field(&mut self, - _: &str, - idx: usize, - f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_enum_variant_arg(idx, f) - } - - - fn emit_struct(&mut self, _: &str, len: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if len == 0 { - try!(write!(self.writer, "{{}}")); - } else { - try!(write!(self.writer, "{{")); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent += indent; - } - try!(f(self)); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent -= indent; - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, *curr_indent)); - } - try!(write!(self.writer, "}}")); - } - Ok(()) - } - - fn emit_struct_field(&mut self, name: &str, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if idx != 0 { - try!(write!(self.writer, ",")); - } - if let EncodingFormat::Pretty{curr_indent, ..} = self.format { - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, curr_indent)); - } - try!(escape_str(self.writer, name)); - if let EncodingFormat::Pretty{..} = self.format { - try!(write!(self.writer, ": ")); - } else { - try!(write!(self.writer, ":")); - } - f(self) - } - - fn emit_tuple(&mut self, len: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_seq(len, f) - } - fn emit_tuple_arg(&mut self, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_seq_elt(idx, f) - } - - fn emit_tuple_struct(&mut self, _: &str, len: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_seq(len, f) - } - fn emit_tuple_struct_arg(&mut self, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_seq_elt(idx, f) - } - - fn emit_option(&mut self, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - f(self) - } - fn emit_option_none(&mut self) -> EncodeResult<()> { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - self.emit_nil() - } - fn emit_option_some(&mut self, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - f(self) - } - - fn emit_seq(&mut self, len: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if len == 0 { - try!(write!(self.writer, "[]")); - } else { - try!(write!(self.writer, "[")); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent += indent; - } - try!(f(self)); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent -= indent; - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, *curr_indent)); - } - try!(write!(self.writer, "]")); - } - Ok(()) - } - - fn emit_seq_elt(&mut self, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if idx != 0 { - try!(write!(self.writer, ",")); - } - if let EncodingFormat::Pretty{ref mut curr_indent, ..} = self.format { - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, *curr_indent)); - } - f(self) - } - - fn emit_map(&mut self, len: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if len == 0 { - try!(write!(self.writer, "{{}}")); - } else { - try!(write!(self.writer, "{{")); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent += indent; - } - try!(f(self)); - if let EncodingFormat::Pretty{ref mut curr_indent, indent} = self.format { - *curr_indent -= indent; - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, *curr_indent)); - } - try!(write!(self.writer, "}}")); - } - Ok(()) - } - - fn emit_map_elt_key(&mut self, idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if idx != 0 { - try!(write!(self.writer, ",")); - } - if let EncodingFormat::Pretty{curr_indent, ..} = self.format { - try!(write!(self.writer, "\n")); - try!(spaces(self.writer, curr_indent)); - } - self.is_emitting_map_key = true; - try!(f(self)); - self.is_emitting_map_key = false; - Ok(()) - } - - fn emit_map_elt_val(&mut self, _idx: usize, f: F) -> EncodeResult<()> where - F: FnOnce(&mut Encoder<'a>) -> EncodeResult<()>, - { - if self.is_emitting_map_key { return Err(EncoderError::BadHashmapKey); } - if let EncodingFormat::Pretty{..} = self.format { - try!(write!(self.writer, ": ")); - } else { - try!(write!(self.writer, ":")); - } - f(self) - } -} - -impl Encodable for Json { - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - match *self { - Json::I64(v) => v.encode(e), - Json::U64(v) => v.encode(e), - Json::F64(v) => v.encode(e), - Json::String(ref v) => v.encode(e), - Json::Boolean(v) => v.encode(e), - Json::Array(ref v) => v.encode(e), - Json::Object(ref v) => v.encode(e), - Json::Null => e.emit_nil(), - } - } -} - -/// Create an `AsJson` wrapper which can be used to print a value as JSON -/// on-the-fly via `write!` -pub fn as_json(t: &T) -> AsJson { - AsJson { inner: t } -} - -/// Create an `AsPrettyJson` wrapper which can be used to print a value as JSON -/// on-the-fly via `write!` -pub fn as_pretty_json(t: &T) -> AsPrettyJson { - AsPrettyJson { inner: t, indent: None } -} - -impl Json { - /// Decodes a json value from an `&mut io::Read` - pub fn from_reader(rdr: &mut io::Read) -> Result { - let contents = { - let mut c = Vec::new(); - try!(rdr.read_to_end(&mut c)); - c - }; - let s = match str::from_utf8(&contents).ok() { - Some(s) => s, - _ => return Err(SyntaxError(NotUtf8, 0, 0)) - }; - let mut builder = Builder::new(s.chars()); - builder.build() - } - - /// Decodes a json value from a string - pub fn from_str(s: &str) -> Result { - let mut builder = Builder::new(s.chars()); - builder.build() - } - - /// Borrow this json object as a pretty object to generate a pretty - /// representation for it via `Display`. - pub fn pretty(&self) -> PrettyJson { - PrettyJson { inner: self } - } - - /// If the Json value is an Object, returns the value associated with the provided key. - /// Otherwise, returns None. - pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ - match self { - &Json::Object(ref map) => map.get(key), - _ => None - } - } - - /// Attempts to get a nested Json Object for each key in `keys`. - /// If any key is found not to exist, find_path will return None. - /// Otherwise, it will return the Json value associated with the final key. - pub fn find_path<'a>(&'a self, keys: &[&str]) -> Option<&'a Json>{ - let mut target = self; - for key in keys.iter() { - match target.find(*key) { - Some(t) => { target = t; }, - None => return None - } - } - Some(target) - } - - /// If the Json value is an Object, performs a depth-first search until - /// a value associated with the provided key is found. If no value is found - /// or the Json value is not an Object, returns None. - pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { - match self { - &Json::Object(ref map) => { - match map.get(key) { - Some(json_value) => Some(json_value), - None => { - for (_, v) in map.iter() { - match v.search(key) { - x if x.is_some() => return x, - _ => () - } - } - None - } - } - }, - _ => None - } - } - - /// Returns true if the Json value is an Object. Returns false otherwise. - pub fn is_object<'a>(&'a self) -> bool { - self.as_object().is_some() - } - - /// If the Json value is an Object, returns a reference to the associated BTreeMap. - /// Returns None otherwise. - pub fn as_object<'a>(&'a self) -> Option<&'a Object> { - match self { - &Json::Object(ref map) => Some(map), - _ => None - } - } - - /// If the Json value is an Object, returns a mutable reference to the associated BTreeMap. - /// Returns None otherwise. - pub fn as_object_mut<'a>(&'a mut self) -> Option<&'a mut Object> { - match self { - &mut Json::Object(ref mut map) => Some(map), - _ => None - } - } - - /// If the Json value is an Object, returns the associated BTreeMap. - /// Returns None otherwise. - pub fn into_object(self) -> Option { - match self { - Json::Object(map) => Some(map), - _ => None - } - } - - /// Returns true if the Json value is an Array. Returns false otherwise. - pub fn is_array<'a>(&'a self) -> bool { - self.as_array().is_some() - } - - /// If the Json value is an Array, returns a reference to the associated vector. - /// Returns None otherwise. - pub fn as_array<'a>(&'a self) -> Option<&'a Array> { - match self { - &Json::Array(ref array) => Some(&*array), - _ => None - } - } - - /// If the Json value is an Array, returns a mutable reference to the associated vector. - /// Returns None otherwise. - pub fn as_array_mut<'a>(&'a mut self) -> Option<&'a mut Array> { - match self { - &mut Json::Array(ref mut list) => Some(list), - _ => None - } - } - - /// If the Json value is an Array, returns the associated vector. - /// Returns None otherwise. - pub fn into_array(self) -> Option { - match self { - Json::Array(array) => Some(array), - _ => None - } - } - - /// Returns true if the Json value is a String. Returns false otherwise. - pub fn is_string<'a>(&'a self) -> bool { - self.as_string().is_some() - } - - /// If the Json value is a String, returns the associated str. - /// Returns None otherwise. - pub fn as_string<'a>(&'a self) -> Option<&'a str> { - match *self { - Json::String(ref s) => Some(&s), - _ => None - } - } - - /// Returns true if the Json value is a Number. Returns false otherwise. - pub fn is_number(&self) -> bool { - match *self { - Json::I64(_) | Json::U64(_) | Json::F64(_) => true, - _ => false, - } - } - - /// Returns true if the Json value is a i64. Returns false otherwise. - pub fn is_i64(&self) -> bool { - match *self { - Json::I64(_) => true, - _ => false, - } - } - - /// Returns true if the Json value is a u64. Returns false otherwise. - pub fn is_u64(&self) -> bool { - match *self { - Json::U64(_) => true, - _ => false, - } - } - - /// Returns true if the Json value is a f64. Returns false otherwise. - pub fn is_f64(&self) -> bool { - match *self { - Json::F64(_) => true, - _ => false, - } - } - - /// If the Json value is a number, return or cast it to a i64. - /// Returns None otherwise. - pub fn as_i64(&self) -> Option { - match *self { - Json::I64(n) => Some(n), - Json::U64(n) if n >= i64::MAX as u64 => None, - Json::U64(n) => Some(n as i64), - _ => None - } - } - - /// If the Json value is a number, return or cast it to a u64. - /// Returns None otherwise. - pub fn as_u64(&self) -> Option { - match *self { - Json::I64(n) if n >= 0 => Some(n as u64), - Json::U64(n) => Some(n), - _ => None - } - } - - /// If the Json value is a number, return or cast it to a f64. - /// Returns None otherwise. - pub fn as_f64(&self) -> Option { - match *self { - Json::I64(n) => Some(n as f64), - Json::U64(n) => Some(n as f64), - Json::F64(n) => Some(n), - _ => None - } - } - - /// Returns true if the Json value is a Boolean. Returns false otherwise. - pub fn is_boolean(&self) -> bool { - self.as_boolean().is_some() - } - - /// If the Json value is a Boolean, returns the associated bool. - /// Returns None otherwise. - pub fn as_boolean(&self) -> Option { - match self { - &Json::Boolean(b) => Some(b), - _ => None - } - } - - /// Returns true if the Json value is a Null. Returns false otherwise. - pub fn is_null(&self) -> bool { - self.as_null().is_some() - } - - /// If the Json value is a Null, returns (). - /// Returns None otherwise. - pub fn as_null(&self) -> Option<()> { - match self { - &Json::Null => Some(()), - _ => None - } - } -} - -impl<'a> Index<&'a str> for Json { - type Output = Json; - - fn index(&self, idx: &str) -> &Json { - self.find(idx).unwrap() - } -} - -impl Index for Json { - type Output = Json; - - fn index<'a>(&'a self, idx: usize) -> &'a Json { - match self { - &Json::Array(ref v) => &v[idx], - _ => panic!("can only index Json with usize if it is an array") - } - } -} - -/// The output of the streaming parser. -#[derive(PartialEq, Debug)] -pub enum JsonEvent { - ObjectStart, - ObjectEnd, - ArrayStart, - ArrayEnd, - BooleanValue(bool), - I64Value(i64), - U64Value(u64), - F64Value(f64), - StringValue(string::String), - NullValue, - Error(ParserError), -} - -#[derive(PartialEq, Debug)] -enum ParserState { - // Parse a value in an array, true means first element. - ParseArray(bool), - // Parse ',' or ']' after an element in an array. - ParseArrayComma, - // Parse a key:value in an object, true means first element. - ParseObject(bool), - // Parse ',' or ']' after an element in an object. - ParseObjectComma, - // Initial state. - ParseStart, - // Expecting the stream to end. - ParseBeforeFinish, - // Parsing can't continue. - ParseFinished, -} - -/// A Stack represents the current position of the parser in the logical -/// structure of the JSON stream. -/// For example foo.bar[3].x -pub struct Stack { - stack: Vec, - str_buffer: Vec, -} - -/// StackElements compose a Stack. -/// For example, Key("foo"), Key("bar"), Index(3) and Key("x") are the -/// StackElements compositing the stack that represents foo.bar[3].x -#[derive(PartialEq, Clone, Debug)] -pub enum StackElement<'l> { - Index(u32), - Key(&'l str), -} - -// Internally, Key elements are stored as indices in a buffer to avoid -// allocating a string for every member of an object. -#[derive(PartialEq, Clone, Debug)] -enum InternalStackElement { - InternalIndex(u32), - InternalKey(u16, u16), // start, size -} - -impl Stack { - pub fn new() -> Stack { - Stack { stack: Vec::new(), str_buffer: Vec::new() } - } - - /// Returns The number of elements in the Stack. - pub fn len(&self) -> usize { self.stack.len() } - - /// Returns true if the stack is empty. - pub fn is_empty(&self) -> bool { self.stack.is_empty() } - - /// Provides access to the StackElement at a given index. - /// lower indices are at the bottom of the stack while higher indices are - /// at the top. - pub fn get<'l>(&'l self, idx: usize) -> StackElement<'l> { - match self.stack[idx] { - InternalIndex(i) => StackElement::Index(i), - InternalKey(start, size) => { - StackElement::Key(str::from_utf8( - &self.str_buffer[start as usize .. start as usize + size as usize]).unwrap()) - } - } - } - - /// Compares this stack with an array of StackElements. - pub fn is_equal_to(&self, rhs: &[StackElement]) -> bool { - if self.stack.len() != rhs.len() { return false; } - for i in 0..rhs.len() { - if self.get(i) != rhs[i] { return false; } - } - return true; - } - - /// Returns true if the bottom-most elements of this stack are the same as - /// the ones passed as parameter. - pub fn starts_with(&self, rhs: &[StackElement]) -> bool { - if self.stack.len() < rhs.len() { return false; } - for i in 0..rhs.len() { - if self.get(i) != rhs[i] { return false; } - } - return true; - } - - /// Returns true if the top-most elements of this stack are the same as - /// the ones passed as parameter. - pub fn ends_with(&self, rhs: &[StackElement]) -> bool { - if self.stack.len() < rhs.len() { return false; } - let offset = self.stack.len() - rhs.len(); - for i in 0..rhs.len() { - if self.get(i + offset) != rhs[i] { return false; } - } - return true; - } - - /// Returns the top-most element (if any). - pub fn top<'l>(&'l self) -> Option> { - return match self.stack.last() { - None => None, - Some(&InternalIndex(i)) => Some(StackElement::Index(i)), - Some(&InternalKey(start, size)) => { - Some(StackElement::Key(str::from_utf8( - &self.str_buffer[start as usize .. (start+size) as usize] - ).unwrap())) - } - } - } - - // Used by Parser to insert Key elements at the top of the stack. - fn push_key(&mut self, key: string::String) { - self.stack.push(InternalKey(self.str_buffer.len() as u16, key.len() as u16)); - for c in key.as_bytes().iter() { - self.str_buffer.push(*c); - } - } - - // Used by Parser to insert Index elements at the top of the stack. - fn push_index(&mut self, index: u32) { - self.stack.push(InternalIndex(index)); - } - - // Used by Parser to remove the top-most element of the stack. - fn pop(&mut self) { - assert!(!self.is_empty()); - match *self.stack.last().unwrap() { - InternalKey(_, sz) => { - let new_size = self.str_buffer.len() - sz as usize; - self.str_buffer.truncate(new_size); - } - InternalIndex(_) => {} - } - self.stack.pop(); - } - - // Used by Parser to test whether the top-most element is an index. - fn last_is_index(&self) -> bool { - if self.is_empty() { return false; } - return match *self.stack.last().unwrap() { - InternalIndex(_) => true, - _ => false, - } - } - - // Used by Parser to increment the index of the top-most element. - fn bump_index(&mut self) { - let len = self.stack.len(); - let idx = match *self.stack.last().unwrap() { - InternalIndex(i) => { i + 1 } - _ => { panic!(); } - }; - self.stack[len - 1] = InternalIndex(idx); - } -} - -/// A streaming JSON parser implemented as an iterator of JsonEvent, consuming -/// an iterator of char. -pub struct Parser { - rdr: T, - ch: Option, - line: usize, - col: usize, - // We maintain a stack representing where we are in the logical structure - // of the JSON stream. - stack: Stack, - // A state machine is kept to make it possible to interrupt and resume parsing. - state: ParserState, -} - -impl> Iterator for Parser { - type Item = JsonEvent; - - fn next(&mut self) -> Option { - if self.state == ParseFinished { - return None; - } - - if self.state == ParseBeforeFinish { - self.parse_whitespace(); - // Make sure there is no trailing characters. - if self.eof() { - self.state = ParseFinished; - return None; - } else { - return Some(self.error_event(TrailingCharacters)); - } - } - - return Some(self.parse()); - } -} - -impl> Parser { - /// Creates the JSON parser. - pub fn new(rdr: T) -> Parser { - let mut p = Parser { - rdr: rdr, - ch: Some('\x00'), - line: 1, - col: 0, - stack: Stack::new(), - state: ParseStart, - }; - p.bump(); - return p; - } - - /// Provides access to the current position in the logical structure of the - /// JSON stream. - pub fn stack<'l>(&'l self) -> &'l Stack { - return &self.stack; - } - - fn eof(&self) -> bool { self.ch.is_none() } - fn ch_or_null(&self) -> char { self.ch.unwrap_or('\x00') } - fn bump(&mut self) { - self.ch = self.rdr.next(); - - if self.ch_is('\n') { - self.line += 1; - self.col = 1; - } else { - self.col += 1; - } - } - - fn next_char(&mut self) -> Option { - self.bump(); - self.ch - } - fn ch_is(&self, c: char) -> bool { - self.ch == Some(c) - } - - fn error(&self, reason: ErrorCode) -> Result { - Err(SyntaxError(reason, self.line, self.col)) - } - - fn parse_whitespace(&mut self) { - while self.ch_is(' ') || - self.ch_is('\n') || - self.ch_is('\t') || - self.ch_is('\r') { self.bump(); } - } - - fn parse_number(&mut self) -> JsonEvent { - let mut neg = false; - - if self.ch_is('-') { - self.bump(); - neg = true; - } - - let res = match self.parse_u64() { - Ok(res) => res, - Err(e) => { return Error(e); } - }; - - if self.ch_is('.') || self.ch_is('e') || self.ch_is('E') { - let mut res = res as f64; - - if self.ch_is('.') { - res = match self.parse_decimal(res) { - Ok(res) => res, - Err(e) => { return Error(e); } - }; - } - - if self.ch_is('e') || self.ch_is('E') { - res = match self.parse_exponent(res) { - Ok(res) => res, - Err(e) => { return Error(e); } - }; - } - - if neg { - res *= -1.0; - } - - F64Value(res) - } else { - if neg { - // Make sure we don't underflow. - if res > (i64::MAX as u64) + 1 { - Error(SyntaxError(InvalidNumber, self.line, self.col)) - } else if res == 0 { - I64Value(res as i64) - } else { - I64Value((!res + 1) as i64) - } - } else { - U64Value(res) - } - } - } - - fn parse_u64(&mut self) -> Result { - let mut accum: u64 = 0; - - match self.ch_or_null() { - '0' => { - self.bump(); - - // A leading '0' must be the only digit before the decimal point. - match self.ch_or_null() { - '0' ... '9' => return self.error(InvalidNumber), - _ => () - } - }, - '1' ... '9' => { - while !self.eof() { - match self.ch_or_null() { - c @ '0' ... '9' => { - macro_rules! try_or_invalid { - ($e: expr) => { - match $e { - Some(v) => v, - None => return self.error(InvalidNumber) - } - } - } - accum = try_or_invalid!(accum.checked_mul(10)); - accum = try_or_invalid!(accum.checked_add((c as u64) - ('0' as u64))); - - self.bump(); - } - _ => break, - } - } - } - _ => return self.error(InvalidNumber), - } - - Ok(accum) - } - - fn parse_decimal(&mut self, mut res: f64) -> Result { - self.bump(); - - // Make sure a digit follows the decimal place. - match self.ch_or_null() { - '0' ... '9' => (), - _ => return self.error(InvalidNumber) - } - - let mut dec = 1.0; - let mut frac = 0.0; - while !self.eof() { - match self.ch_or_null() { - c @ '0' ... '9' => { - dec /= 10.0; - frac += (((c as isize) - ('0' as isize)) as f64) * dec; - self.bump(); - } - _ => break, - } - } - - res += frac; - - Ok(res) - } - - fn parse_exponent(&mut self, mut res: f64) -> Result { - self.bump(); - - let mut exp = 0; - let mut neg_exp = false; - - if self.ch_is('+') { - self.bump(); - } else if self.ch_is('-') { - self.bump(); - neg_exp = true; - } - - // Make sure a digit follows the exponent place. - match self.ch_or_null() { - '0' ... '9' => (), - _ => return self.error(InvalidNumber) - } - while !self.eof() { - match self.ch_or_null() { - c @ '0' ... '9' => { - exp *= 10; - exp += (c as usize) - ('0' as usize); - - self.bump(); - } - _ => break - } - } - - let exp = 10_f64.powi(exp as i32); - if neg_exp { - res /= exp; - } else { - res *= exp; - } - - Ok(res) - } - - fn decode_hex_escape(&mut self) -> Result { - let mut i = 0; - let mut n = 0; - while i < 4 { - self.bump(); - n = match self.ch_or_null() { - c @ '0' ... '9' => n * 16 + ((c as u16) - ('0' as u16)), - c @ 'a' ... 'f' => n * 16 + (10 + (c as u16) - ('a' as u16)), - c @ 'A' ... 'F' => n * 16 + (10 + (c as u16) - ('A' as u16)), - _ => return self.error(InvalidEscape) - }; - - i += 1; - } - - Ok(n) - } - - fn parse_str(&mut self) -> Result { - let mut escape = false; - let mut res = string::String::new(); - - loop { - self.bump(); - if self.eof() { - return self.error(EOFWhileParsingString); - } - - if escape { - match self.ch_or_null() { - '"' => res.push('"'), - '\\' => res.push('\\'), - '/' => res.push('/'), - 'b' => res.push('\x08'), - 'f' => res.push('\x0c'), - 'n' => res.push('\n'), - 'r' => res.push('\r'), - 't' => res.push('\t'), - 'u' => match try!(self.decode_hex_escape()) { - 0xDC00 ... 0xDFFF => { - return self.error(LoneLeadingSurrogateInHexEscape) - } - - // Non-BMP characters are encoded as a sequence of - // two hex escapes, representing UTF-16 surrogates. - n1 @ 0xD800 ... 0xDBFF => { - match (self.next_char(), self.next_char()) { - (Some('\\'), Some('u')) => (), - _ => return self.error(UnexpectedEndOfHexEscape), - } - - let n2 = try!(self.decode_hex_escape()); - if n2 < 0xDC00 || n2 > 0xDFFF { - return self.error(LoneLeadingSurrogateInHexEscape) - } - let c = (((n1 - 0xD800) as u32) << 10 | - (n2 - 0xDC00) as u32) + 0x1_0000; - res.push(char::from_u32(c).unwrap()); - } - - n => match char::from_u32(n as u32) { - Some(c) => res.push(c), - None => return self.error(InvalidUnicodeCodePoint), - }, - }, - _ => return self.error(InvalidEscape), - } - escape = false; - } else if self.ch_is('\\') { - escape = true; - } else { - match self.ch { - Some('"') => { - self.bump(); - return Ok(res); - }, - Some(c) if c <= '\u{1F}' => - return self.error(ControlCharacterInString), - Some(c) => res.push(c), - None => unreachable!() - } - } - } - } - - // Invoked at each iteration, consumes the stream until it has enough - // information to return a JsonEvent. - // Manages an internal state so that parsing can be interrupted and resumed. - // Also keeps track of the position in the logical structure of the json - // stream int the form of a stack that can be queried by the user using the - // stack() method. - fn parse(&mut self) -> JsonEvent { - loop { - // The only paths where the loop can spin a new iteration - // are in the cases ParseArrayComma and ParseObjectComma if ',' - // is parsed. In these cases the state is set to (respectively) - // ParseArray(false) and ParseObject(false), which always return, - // so there is no risk of getting stuck in an infinite loop. - // All other paths return before the end of the loop's iteration. - self.parse_whitespace(); - - match self.state { - ParseStart => { - return self.parse_start(); - } - ParseArray(first) => { - return self.parse_array(first); - } - ParseArrayComma => { - match self.parse_array_comma_or_end() { - Some(evt) => { return evt; } - None => {} - } - } - ParseObject(first) => { - return self.parse_object(first); - } - ParseObjectComma => { - self.stack.pop(); - if self.ch_is(',') { - self.state = ParseObject(false); - self.bump(); - } else { - return self.parse_object_end(); - } - } - _ => { - return self.error_event(InvalidSyntax); - } - } - } - } - - fn parse_start(&mut self) -> JsonEvent { - let val = self.parse_value(); - self.state = match val { - Error(_) => ParseFinished, - ArrayStart => ParseArray(true), - ObjectStart => ParseObject(true), - _ => ParseBeforeFinish, - }; - return val; - } - - fn parse_array(&mut self, first: bool) -> JsonEvent { - if self.ch_is(']') { - if !first { - self.error_event(InvalidSyntax) - } else { - self.state = if self.stack.is_empty() { - ParseBeforeFinish - } else if self.stack.last_is_index() { - ParseArrayComma - } else { - ParseObjectComma - }; - self.bump(); - ArrayEnd - } - } else { - if first { - self.stack.push_index(0); - } - let val = self.parse_value(); - self.state = match val { - Error(_) => ParseFinished, - ArrayStart => ParseArray(true), - ObjectStart => ParseObject(true), - _ => ParseArrayComma, - }; - val - } - } - - fn parse_array_comma_or_end(&mut self) -> Option { - if self.ch_is(',') { - self.stack.bump_index(); - self.state = ParseArray(false); - self.bump(); - None - } else if self.ch_is(']') { - self.stack.pop(); - self.state = if self.stack.is_empty() { - ParseBeforeFinish - } else if self.stack.last_is_index() { - ParseArrayComma - } else { - ParseObjectComma - }; - self.bump(); - Some(ArrayEnd) - } else if self.eof() { - Some(self.error_event(EOFWhileParsingArray)) - } else { - Some(self.error_event(InvalidSyntax)) - } - } - - fn parse_object(&mut self, first: bool) -> JsonEvent { - if self.ch_is('}') { - if !first { - if self.stack.is_empty() { - return self.error_event(TrailingComma); - } else { - self.stack.pop(); - } - } - self.state = if self.stack.is_empty() { - ParseBeforeFinish - } else if self.stack.last_is_index() { - ParseArrayComma - } else { - ParseObjectComma - }; - self.bump(); - return ObjectEnd; - } - if self.eof() { - return self.error_event(EOFWhileParsingObject); - } - if !self.ch_is('"') { - return self.error_event(KeyMustBeAString); - } - let s = match self.parse_str() { - Ok(s) => s, - Err(e) => { - self.state = ParseFinished; - return Error(e); - } - }; - self.parse_whitespace(); - if self.eof() { - return self.error_event(EOFWhileParsingObject); - } else if self.ch_or_null() != ':' { - return self.error_event(ExpectedColon); - } - self.stack.push_key(s); - self.bump(); - self.parse_whitespace(); - - let val = self.parse_value(); - - self.state = match val { - Error(_) => ParseFinished, - ArrayStart => ParseArray(true), - ObjectStart => ParseObject(true), - _ => ParseObjectComma, - }; - return val; - } - - fn parse_object_end(&mut self) -> JsonEvent { - if self.ch_is('}') { - self.state = if self.stack.is_empty() { - ParseBeforeFinish - } else if self.stack.last_is_index() { - ParseArrayComma - } else { - ParseObjectComma - }; - self.bump(); - ObjectEnd - } else if self.eof() { - self.error_event(EOFWhileParsingObject) - } else { - self.error_event(InvalidSyntax) - } - } - - fn parse_value(&mut self) -> JsonEvent { - if self.eof() { return self.error_event(EOFWhileParsingValue); } - match self.ch_or_null() { - 'n' => { self.parse_ident("ull", NullValue) } - 't' => { self.parse_ident("rue", BooleanValue(true)) } - 'f' => { self.parse_ident("alse", BooleanValue(false)) } - '0' ... '9' | '-' => self.parse_number(), - '"' => match self.parse_str() { - Ok(s) => StringValue(s), - Err(e) => Error(e), - }, - '[' => { - self.bump(); - ArrayStart - } - '{' => { - self.bump(); - ObjectStart - } - _ => { self.error_event(InvalidSyntax) } - } - } - - fn parse_ident(&mut self, ident: &str, value: JsonEvent) -> JsonEvent { - if ident.chars().all(|c| Some(c) == self.next_char()) { - self.bump(); - value - } else { - Error(SyntaxError(InvalidSyntax, self.line, self.col)) - } - } - - fn error_event(&mut self, reason: ErrorCode) -> JsonEvent { - self.state = ParseFinished; - Error(SyntaxError(reason, self.line, self.col)) - } -} - -/// A Builder consumes a json::Parser to create a generic Json structure. -pub struct Builder { - parser: Parser, - token: Option, -} - -impl> Builder { - /// Create a JSON Builder. - pub fn new(src: T) -> Builder { - Builder { parser: Parser::new(src), token: None, } - } - - // Decode a Json value from a Parser. - pub fn build(&mut self) -> Result { - self.bump(); - let result = self.build_value(); - self.bump(); - match self.token.take() { - None => {} - Some(Error(e)) => { return Err(e); } - _ => { return Err(SyntaxError(InvalidSyntax, self.parser.line, self.parser.col)); } - } - result - } - - fn bump(&mut self) { - self.token = self.parser.next(); - } - - fn build_value(&mut self) -> Result { - return match self.token.take() { - Some(NullValue) => Ok(Json::Null), - Some(I64Value(n)) => Ok(Json::I64(n)), - Some(U64Value(n)) => Ok(Json::U64(n)), - Some(F64Value(n)) => Ok(Json::F64(n)), - Some(BooleanValue(b)) => Ok(Json::Boolean(b)), - Some(StringValue(ref mut s)) => { - let mut temp = string::String::new(); - swap(s, &mut temp); - Ok(Json::String(temp)) - } - Some(Error(e)) => Err(e), - Some(ArrayStart) => self.build_array(), - Some(ObjectStart) => self.build_object(), - Some(ObjectEnd) => self.parser.error(InvalidSyntax), - Some(ArrayEnd) => self.parser.error(InvalidSyntax), - None => self.parser.error(EOFWhileParsingValue), - } - } - - fn build_array(&mut self) -> Result { - self.bump(); - let mut values = Vec::new(); - - loop { - if let Some(ArrayEnd) = self.token { - return Ok(Json::Array(values.into_iter().collect())); - } - match self.build_value() { - Ok(v) => values.push(v), - Err(e) => { return Err(e) } - } - self.bump(); - } - } - - fn build_object(&mut self) -> Result { - self.bump(); - - let mut values = BTreeMap::new(); - - loop { - match self.token.take() { - Some(ObjectEnd) => { return Ok(Json::Object(values)); } - Some(Error(e)) => { return Err(e); } - None => { break; } - token => { self.token = token; } - } - let key = match self.parser.stack().top() { - Some(StackElement::Key(k)) => { k.to_string() } - _ => { panic!("invalid state"); } - }; - match self.build_value() { - Ok(value) => { values.insert(key, value); } - Err(e) => { return Err(e); } - } - self.bump(); - } - return self.parser.error(EOFWhileParsingObject); - } -} - -/// A structure to decode JSON to values in rust. -pub struct Decoder { - stack: Vec, -} - -impl Decoder { - /// Creates a new decoder instance for decoding the specified JSON value. - pub fn new(json: Json) -> Decoder { - Decoder { stack: vec![json] } - } -} - -impl Decoder { - fn pop(&mut self) -> DecodeResult { - match self.stack.pop() { - Some(s) => Ok(s), - None => Err(EOF), - } - } -} - -macro_rules! expect { - ($e:expr, Null) => ({ - match try!($e) { - Json::Null => Ok(()), - other => Err(ExpectedError("Null".to_string(), - format!("{}", other))) - } - }); - ($e:expr, $t:ident) => ({ - match try!($e) { - Json::$t(v) => Ok(v), - other => { - Err(ExpectedError(stringify!($t).to_string(), - format!("{}", other))) - } - } - }) -} - -macro_rules! read_primitive { - ($name:ident, $ty:ident) => { - #[allow(unused_comparisons)] - fn $name(&mut self) -> DecodeResult<$ty> { - match try!(self.pop()) { - Json::I64(i) => { - let other = i as $ty; - if i == other as i64 && (other > 0) == (i > 0) { - Ok(other) - } else { - Err(ExpectedError("Number".to_string(), i.to_string())) - } - } - Json::U64(u) => { - let other = u as $ty; - if u == other as u64 && other >= 0 { - Ok(other) - } else { - Err(ExpectedError("Number".to_string(), u.to_string())) - } - } - Json::F64(f) => { - Err(ExpectedError("Integer".to_string(), f.to_string())) - } - // re: #12967.. a type w/ numeric keys (ie HashMap etc) - // is going to have a string here, as per JSON spec. - Json::String(s) => match s.parse() { - Ok(f) => Ok(f), - Err(_) => Err(ExpectedError("Number".to_string(), s)), - }, - value => { - Err(ExpectedError("Number".to_string(), value.to_string())) - } - } - } - } -} - -impl ::Decoder for Decoder { - type Error = DecoderError; - - fn read_nil(&mut self) -> DecodeResult<()> { - expect!(self.pop(), Null) - } - - read_primitive! { read_usize, usize } - read_primitive! { read_u8, u8 } - read_primitive! { read_u16, u16 } - read_primitive! { read_u32, u32 } - read_primitive! { read_u64, u64 } - read_primitive! { read_isize, isize } - read_primitive! { read_i8, i8 } - read_primitive! { read_i16, i16 } - read_primitive! { read_i32, i32 } - read_primitive! { read_i64, i64 } - - fn read_f32(&mut self) -> DecodeResult { - self.read_f64().map(|x| x as f32) - } - - fn read_f64(&mut self) -> DecodeResult { - match try!(self.pop()) { - Json::I64(f) => Ok(f as f64), - Json::U64(f) => Ok(f as f64), - Json::F64(f) => Ok(f), - Json::String(s) => { - // re: #12967.. a type w/ numeric keys (ie HashMap etc) - // is going to have a string here, as per JSON spec. - match s.parse() { - Ok(f) => Ok(f), - Err(_) => Err(ExpectedError("Number".to_string(), s)), - } - }, - Json::Null => Ok(f64::NAN), - value => Err(ExpectedError("Number".to_string(), format!("{}", value))) - } - } - - fn read_bool(&mut self) -> DecodeResult { - expect!(self.pop(), Boolean) - } - - fn read_char(&mut self) -> DecodeResult { - let s = try!(self.read_str()); - { - let mut it = s.chars(); - match (it.next(), it.next()) { - // exactly one character - (Some(c), None) => return Ok(c), - _ => () - } - } - Err(ExpectedError("single character string".to_string(), format!("{}", s))) - } - - fn read_str(&mut self) -> DecodeResult { - expect!(self.pop(), String) - } - - fn read_enum(&mut self, _name: &str, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - f(self) - } - - fn read_enum_variant(&mut self, names: &[&str], - mut f: F) -> DecodeResult - where F: FnMut(&mut Decoder, usize) -> DecodeResult, - { - let name = match try!(self.pop()) { - Json::String(s) => s, - Json::Object(mut o) => { - let n = match o.remove(&"variant".to_string()) { - Some(Json::String(s)) => s, - Some(val) => { - return Err(ExpectedError("String".to_string(), format!("{}", val))) - } - None => { - return Err(MissingFieldError("variant".to_string())) - } - }; - match o.remove(&"fields".to_string()) { - Some(Json::Array(l)) => { - for field in l.into_iter().rev() { - self.stack.push(field); - } - }, - Some(val) => { - return Err(ExpectedError("Array".to_string(), format!("{}", val))) - } - None => { - return Err(MissingFieldError("fields".to_string())) - } - } - n - } - json => { - return Err(ExpectedError("String or Object".to_string(), format!("{}", json))) - } - }; - let idx = match names.iter().position(|n| *n == name) { - Some(idx) => idx, - None => return Err(UnknownVariantError(name)) - }; - f(self, idx) - } - - fn read_enum_variant_arg(&mut self, _idx: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - f(self) - } - - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) -> DecodeResult where - F: FnMut(&mut Decoder, usize) -> DecodeResult, - { - self.read_enum_variant(names, f) - } - - - fn read_enum_struct_variant_field(&mut self, - _name: &str, - idx: usize, - f: F) - -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - self.read_enum_variant_arg(idx, f) - } - - fn read_struct(&mut self, _name: &str, _len: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - let value = try!(f(self)); - try!(self.pop()); - Ok(value) - } - - fn read_struct_field(&mut self, - name: &str, - _idx: usize, - f: F) - -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - let mut obj = try!(expect!(self.pop(), Object)); - - let value = match obj.remove(&name.to_string()) { - None => { - // Add a Null and try to parse it as an Option<_> - // to get None as a default value. - self.stack.push(Json::Null); - match f(self) { - Ok(x) => x, - Err(_) => return Err(MissingFieldError(name.to_string())), - } - }, - Some(json) => { - self.stack.push(json); - try!(f(self)) - } - }; - self.stack.push(Json::Object(obj)); - Ok(value) - } - - fn read_tuple(&mut self, tuple_len: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - self.read_seq(move |d, len| { - if len == tuple_len { - f(d) - } else { - Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len))) - } - }) - } - - fn read_tuple_arg(&mut self, idx: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - self.read_seq_elt(idx, f) - } - - fn read_tuple_struct(&mut self, - _name: &str, - len: usize, - f: F) - -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - self.read_tuple(len, f) - } - - fn read_tuple_struct_arg(&mut self, - idx: usize, - f: F) - -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - self.read_tuple_arg(idx, f) - } - - fn read_option(&mut self, mut f: F) -> DecodeResult where - F: FnMut(&mut Decoder, bool) -> DecodeResult, - { - match try!(self.pop()) { - Json::Null => f(self, false), - value => { self.stack.push(value); f(self, true) } - } - } - - fn read_seq(&mut self, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder, usize) -> DecodeResult, - { - let array = try!(expect!(self.pop(), Array)); - let len = array.len(); - for v in array.into_iter().rev() { - self.stack.push(v); - } - f(self, len) - } - - fn read_seq_elt(&mut self, _idx: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - f(self) - } - - fn read_map(&mut self, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder, usize) -> DecodeResult, - { - let obj = try!(expect!(self.pop(), Object)); - let len = obj.len(); - for (key, value) in obj.into_iter() { - self.stack.push(value); - self.stack.push(Json::String(key)); - } - f(self, len) - } - - fn read_map_elt_key(&mut self, _idx: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - f(self) - } - - fn read_map_elt_val(&mut self, _idx: usize, f: F) -> DecodeResult where - F: FnOnce(&mut Decoder) -> DecodeResult, - { - f(self) - } - - fn error(&mut self, err: &str) -> DecoderError { - ApplicationError(err.to_string()) - } -} - -/// A trait for converting values to JSON -pub trait ToJson { - /// Converts the value of `self` to an instance of JSON - fn to_json(&self) -> Json; -} - -macro_rules! to_json_impl_i64 { - ($($t:ty), +) => ( - $(impl ToJson for $t { - fn to_json(&self) -> Json { Json::I64(*self as i64) } - })+ - ) -} - -to_json_impl_i64! { isize, i8, i16, i32, i64 } - -macro_rules! to_json_impl_u64 { - ($($t:ty), +) => ( - $(impl ToJson for $t { - fn to_json(&self) -> Json { Json::U64(*self as u64) } - })+ - ) -} - -to_json_impl_u64! { usize, u8, u16, u32, u64 } - -impl ToJson for Json { - fn to_json(&self) -> Json { self.clone() } -} - -impl ToJson for f32 { - fn to_json(&self) -> Json { (*self as f64).to_json() } -} - -impl ToJson for f64 { - fn to_json(&self) -> Json { - use std::num::FpCategory::{Nan, Infinite}; - - match self.classify() { - Nan | Infinite => Json::Null, - _ => Json::F64(*self) - } - } -} - -impl ToJson for () { - fn to_json(&self) -> Json { Json::Null } -} - -impl ToJson for bool { - fn to_json(&self) -> Json { Json::Boolean(*self) } -} - -impl ToJson for str { - fn to_json(&self) -> Json { Json::String(self.to_string()) } -} - -impl ToJson for string::String { - fn to_json(&self) -> Json { Json::String((*self).clone()) } -} - -macro_rules! tuple_impl { - // use variables to indicate the arity of the tuple - ($($tyvar:ident),* ) => { - // the trailing commas are for the 1 tuple - impl< - $( $tyvar : ToJson ),* - > ToJson for ( $( $tyvar ),* , ) { - - #[inline] - #[allow(non_snake_case)] - fn to_json(&self) -> Json { - match *self { - ($(ref $tyvar),*,) => Json::Array(vec![$($tyvar.to_json()),*]) - } - } - } - } -} - -tuple_impl!{A} -tuple_impl!{A, B} -tuple_impl!{A, B, C} -tuple_impl!{A, B, C, D} -tuple_impl!{A, B, C, D, E} -tuple_impl!{A, B, C, D, E, F} -tuple_impl!{A, B, C, D, E, F, G} -tuple_impl!{A, B, C, D, E, F, G, H} -tuple_impl!{A, B, C, D, E, F, G, H, I} -tuple_impl!{A, B, C, D, E, F, G, H, I, J} -tuple_impl!{A, B, C, D, E, F, G, H, I, J, K} -tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L} - -impl ToJson for [A] { - fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) } -} - -impl ToJson for Vec { - fn to_json(&self) -> Json { Json::Array(self.iter().map(|elt| elt.to_json()).collect()) } -} - -impl ToJson for BTreeMap { - fn to_json(&self) -> Json { - let mut d = BTreeMap::new(); - for (key, value) in self.iter() { - d.insert((*key).clone(), value.to_json()); - } - Json::Object(d) - } -} - -impl ToJson for HashMap { - fn to_json(&self) -> Json { - let mut d = BTreeMap::new(); - for (key, value) in self.iter() { - d.insert((*key).clone(), value.to_json()); - } - Json::Object(d) - } -} - -impl ToJson for Option { - fn to_json(&self) -> Json { - match *self { - None => Json::Null, - Some(ref value) => value.to_json() - } - } -} - -struct FormatShim<'a, 'b: 'a> { - inner: &'a mut fmt::Formatter<'b>, -} - -impl<'a, 'b> fmt::Write for FormatShim<'a, 'b> { - fn write_str(&mut self, s: &str) -> fmt::Result { - match self.inner.write_str(s) { - Ok(_) => Ok(()), - Err(_) => Err(fmt::Error) - } - } -} - -impl fmt::Display for Json { - /// Encodes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut shim = FormatShim { inner: f }; - let mut encoder = Encoder::new(&mut shim); - match self.encode(&mut encoder) { - Ok(_) => Ok(()), - Err(_) => Err(fmt::Error) - } - } -} - -impl<'a> fmt::Display for PrettyJson<'a> { - /// Encodes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut shim = FormatShim { inner: f }; - let mut encoder = Encoder::new_pretty(&mut shim); - match self.inner.encode(&mut encoder) { - Ok(_) => Ok(()), - Err(_) => Err(fmt::Error) - } - } -} - -impl<'a, T: Encodable> fmt::Display for AsJson<'a, T> { - /// Encodes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut shim = FormatShim { inner: f }; - let mut encoder = Encoder::new(&mut shim); - match self.inner.encode(&mut encoder) { - Ok(_) => Ok(()), - Err(_) => Err(fmt::Error) - } - } -} - -impl<'a, T> AsPrettyJson<'a, T> { - /// Set the indentation level for the emitted JSON - pub fn indent(mut self, indent: u32) -> AsPrettyJson<'a, T> { - self.indent = Some(indent); - self - } -} - -impl<'a, T: Encodable> fmt::Display for AsPrettyJson<'a, T> { - /// Encodes a json value into a string - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut shim = FormatShim { inner: f }; - let mut encoder = Encoder::new_pretty(&mut shim); - if let Some(n) = self.indent { - // unwrap cannot panic for pretty encoders - let _ = encoder.set_indent(n); - } - match self.inner.encode(&mut encoder) { - Ok(_) => Ok(()), - Err(_) => Err(fmt::Error) - } - } -} - -impl FromStr for Json { - type Err = ParserError; - fn from_str(s: &str) -> Result { - Json::from_str(s) - } -} - -#[cfg(test)] -mod tests { - use self::Animal::*; - use {Encodable, Decodable}; - use super::Json::*; - use super::ErrorCode::*; - use super::ParserError::*; - use super::DecoderError::*; - use super::JsonEvent::*; - use super::StackElement::*; - use super::{Json, DecodeResult, DecoderError, JsonEvent, Parser, - StackElement, Stack, Decoder, Encoder, EncoderError}; - use std::{i64, u64, f32, f64}; - use std::collections::BTreeMap; - use std::string; - - #[derive(RustcDecodable, Eq, PartialEq, Debug)] - struct OptionData { - opt: Option, - } - - #[test] - fn test_decode_option_none() { - let s ="{}"; - let obj: OptionData = super::decode(s).unwrap(); - assert_eq!(obj, OptionData { opt: None }); - } - - #[test] - fn test_decode_option_some() { - let s = "{ \"opt\": 10 }"; - let obj: OptionData = super::decode(s).unwrap(); - assert_eq!(obj, OptionData { opt: Some(10) }); - } - - #[test] - fn test_decode_option_malformed() { - check_err::("{ \"opt\": [] }", - ExpectedError("Number".to_string(), "[]".to_string())); - check_err::("{ \"opt\": false }", - ExpectedError("Number".to_string(), "false".to_string())); - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - enum Animal { - Dog, - Frog(string::String, isize) - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - struct Inner { - a: (), - b: usize, - c: Vec, - } - - #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)] - struct Outer { - inner: Vec, - } - - fn mk_object(items: &[(string::String, Json)]) -> Json { - let mut d = BTreeMap::new(); - - for item in items.iter() { - match *item { - (ref key, ref value) => { d.insert((*key).clone(), (*value).clone()); }, - } - }; - - Object(d) - } - - #[test] - fn test_from_str_trait() { - let s = "null"; - assert!(s.parse::().unwrap() == s.parse().unwrap()); - } - - #[test] - fn test_write_null() { - assert_eq!(Null.to_string(), "null"); - assert_eq!(Null.pretty().to_string(), "null"); - } - - #[test] - fn test_write_i64() { - assert_eq!(U64(0).to_string(), "0"); - assert_eq!(U64(0).pretty().to_string(), "0"); - - assert_eq!(U64(1234).to_string(), "1234"); - assert_eq!(U64(1234).pretty().to_string(), "1234"); - - assert_eq!(I64(-5678).to_string(), "-5678"); - assert_eq!(I64(-5678).pretty().to_string(), "-5678"); - - assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); - assert_eq!(U64(7650007200025252000).pretty().to_string(), "7650007200025252000"); - } - - #[test] - fn test_write_f64() { - assert_eq!(F64(3.0).to_string(), "3.0"); - assert_eq!(F64(3.0).pretty().to_string(), "3.0"); - - assert_eq!(F64(3.1).to_string(), "3.1"); - assert_eq!(F64(3.1).pretty().to_string(), "3.1"); - - assert_eq!(F64(-1.5).to_string(), "-1.5"); - assert_eq!(F64(-1.5).pretty().to_string(), "-1.5"); - - assert_eq!(F64(0.5).to_string(), "0.5"); - assert_eq!(F64(0.5).pretty().to_string(), "0.5"); - - assert_eq!(F64(f64::NAN).to_string(), "null"); - assert_eq!(F64(f64::NAN).pretty().to_string(), "null"); - - assert_eq!(F64(f64::INFINITY).to_string(), "null"); - assert_eq!(F64(f64::INFINITY).pretty().to_string(), "null"); - - assert_eq!(F64(f64::NEG_INFINITY).to_string(), "null"); - assert_eq!(F64(f64::NEG_INFINITY).pretty().to_string(), "null"); - } - - #[test] - fn test_write_str() { - assert_eq!(String("".to_string()).to_string(), "\"\""); - assert_eq!(String("".to_string()).pretty().to_string(), "\"\""); - - assert_eq!(String("homura".to_string()).to_string(), "\"homura\""); - assert_eq!(String("madoka".to_string()).pretty().to_string(), "\"madoka\""); - } - - #[test] - fn test_write_bool() { - assert_eq!(Boolean(true).to_string(), "true"); - assert_eq!(Boolean(true).pretty().to_string(), "true"); - - assert_eq!(Boolean(false).to_string(), "false"); - assert_eq!(Boolean(false).pretty().to_string(), "false"); - } - - #[test] - fn test_write_array() { - assert_eq!(Array(vec![]).to_string(), "[]"); - assert_eq!(Array(vec![]).pretty().to_string(), "[]"); - - assert_eq!(Array(vec![Boolean(true)]).to_string(), "[true]"); - assert_eq!( - Array(vec![Boolean(true)]).pretty().to_string(), - "\ - [\n \ - true\n\ - ]" - ); - - let long_test_array = Array(vec![ - Boolean(false), - Null, - Array(vec![String("foo\nbar".to_string()), F64(3.5)])]); - - assert_eq!(long_test_array.to_string(), - "[false,null,[\"foo\\nbar\",3.5]]"); - assert_eq!( - long_test_array.pretty().to_string(), - "\ - [\n \ - false,\n \ - null,\n \ - [\n \ - \"foo\\nbar\",\n \ - 3.5\n \ - ]\n\ - ]" - ); - } - - #[test] - fn test_write_object() { - assert_eq!(mk_object(&[]).to_string(), "{}"); - assert_eq!(mk_object(&[]).pretty().to_string(), "{}"); - - assert_eq!( - mk_object(&[ - ("a".to_string(), Boolean(true)) - ]).to_string(), - "{\"a\":true}" - ); - assert_eq!( - mk_object(&[("a".to_string(), Boolean(true))]).pretty().to_string(), - "\ - {\n \ - \"a\": true\n\ - }" - ); - - let complex_obj = mk_object(&[ - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) - ])) - ]); - - assert_eq!( - complex_obj.to_string(), - "{\ - \"b\":[\ - {\"c\":\"\\f\\r\"},\ - {\"d\":\"\"}\ - ]\ - }" - ); - assert_eq!( - complex_obj.pretty().to_string(), - "\ - {\n \ - \"b\": [\n \ - {\n \ - \"c\": \"\\f\\r\"\n \ - },\n \ - {\n \ - \"d\": \"\"\n \ - }\n \ - ]\n\ - }" - ); - - let a = mk_object(&[ - ("a".to_string(), Boolean(true)), - ("b".to_string(), Array(vec![ - mk_object(&[("c".to_string(), String("\x0c\r".to_string()))]), - mk_object(&[("d".to_string(), String("".to_string()))]) - ])) - ]); - - // We can't compare the strings directly because the object fields be - // printed in a different order. - assert_eq!(a.clone(), a.to_string().parse().unwrap()); - assert_eq!(a.clone(), a.pretty().to_string().parse().unwrap()); - } - - #[test] - fn test_write_enum() { - let animal = Dog; - assert_eq!( - format!("{}", super::as_json(&animal)), - "\"Dog\"" - ); - assert_eq!( - format!("{}", super::as_pretty_json(&animal)), - "\"Dog\"" - ); - - let animal = Frog("Henry".to_string(), 349); - assert_eq!( - format!("{}", super::as_json(&animal)), - "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}" - ); - assert_eq!( - format!("{}", super::as_pretty_json(&animal)), - "{\n \ - \"variant\": \"Frog\",\n \ - \"fields\": [\n \ - \"Henry\",\n \ - 349\n \ - ]\n\ - }" - ); - } - - macro_rules! check_encoder_for_simple { - ($value:expr, $expected:expr) => ({ - let s = format!("{}", super::as_json(&$value)); - assert_eq!(s, $expected); - - let s = format!("{}", super::as_pretty_json(&$value)); - assert_eq!(s, $expected); - }) - } - - #[test] - fn test_write_some() { - check_encoder_for_simple!(Some("jodhpurs".to_string()), "\"jodhpurs\""); - } - - #[test] - fn test_write_none() { - check_encoder_for_simple!(None::, "null"); - } - - #[test] - fn test_write_char() { - check_encoder_for_simple!('a', "\"a\""); - check_encoder_for_simple!('\t', "\"\\t\""); - check_encoder_for_simple!('\u{0000}', "\"\\u0000\""); - check_encoder_for_simple!('\u{001b}', "\"\\u001b\""); - check_encoder_for_simple!('\u{007f}', "\"\\u007f\""); - check_encoder_for_simple!('\u{00a0}', "\"\u{00a0}\""); - check_encoder_for_simple!('\u{abcd}', "\"\u{abcd}\""); - check_encoder_for_simple!('\u{10ffff}', "\"\u{10ffff}\""); - } - - #[test] - fn test_trailing_characters() { - assert_eq!(Json::from_str("nulla"), Err(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(Json::from_str("truea"), Err(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(Json::from_str("falsea"), Err(SyntaxError(TrailingCharacters, 1, 6))); - assert_eq!(Json::from_str("1a"), Err(SyntaxError(TrailingCharacters, 1, 2))); - assert_eq!(Json::from_str("[]a"), Err(SyntaxError(TrailingCharacters, 1, 3))); - assert_eq!(Json::from_str("{}a"), Err(SyntaxError(TrailingCharacters, 1, 3))); - } - - #[test] - fn test_read_identifiers() { - assert_eq!(Json::from_str("n"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(Json::from_str("nul"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(Json::from_str("t"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(Json::from_str("truz"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(Json::from_str("f"), Err(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(Json::from_str("faz"), Err(SyntaxError(InvalidSyntax, 1, 3))); - - assert_eq!(Json::from_str("null"), Ok(Null)); - assert_eq!(Json::from_str("true"), Ok(Boolean(true))); - assert_eq!(Json::from_str("false"), Ok(Boolean(false))); - assert_eq!(Json::from_str(" null "), Ok(Null)); - assert_eq!(Json::from_str(" true "), Ok(Boolean(true))); - assert_eq!(Json::from_str(" false "), Ok(Boolean(false))); - } - - #[test] - fn test_decode_identifiers() { - let v: () = super::decode("null").unwrap(); - assert_eq!(v, ()); - - let v: bool = super::decode("true").unwrap(); - assert_eq!(v, true); - - let v: bool = super::decode("false").unwrap(); - assert_eq!(v, false); - } - - #[test] - fn test_read_number() { - assert_eq!(Json::from_str("+"), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(Json::from_str("."), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(Json::from_str("NaN"), Err(SyntaxError(InvalidSyntax, 1, 1))); - assert_eq!(Json::from_str("-"), Err(SyntaxError(InvalidNumber, 1, 2))); - assert_eq!(Json::from_str("00"), Err(SyntaxError(InvalidNumber, 1, 2))); - assert_eq!(Json::from_str("1."), Err(SyntaxError(InvalidNumber, 1, 3))); - assert_eq!(Json::from_str("1e"), Err(SyntaxError(InvalidNumber, 1, 3))); - assert_eq!(Json::from_str("1e+"), Err(SyntaxError(InvalidNumber, 1, 4))); - - assert_eq!(Json::from_str("18446744073709551616"), Err(SyntaxError(InvalidNumber, 1, 20))); - assert_eq!(Json::from_str("18446744073709551617"), Err(SyntaxError(InvalidNumber, 1, 20))); - assert_eq!(Json::from_str("-9223372036854775809"), Err(SyntaxError(InvalidNumber, 1, 21))); - - assert_eq!(Json::from_str("3"), Ok(U64(3))); - assert_eq!(Json::from_str("3.1"), Ok(F64(3.1))); - assert_eq!(Json::from_str("-1.2"), Ok(F64(-1.2))); - assert_eq!(Json::from_str("0.4"), Ok(F64(0.4))); - assert_eq!(Json::from_str("0.4e5"), Ok(F64(0.4e5))); - assert_eq!(Json::from_str("0.4e+15"), Ok(F64(0.4e15))); - assert_eq!(Json::from_str("0.4e-01"), Ok(F64(0.4e-01))); - assert_eq!(Json::from_str("123456789.5024"), Ok(F64(123456789.5024))); - assert_eq!(Json::from_str(" 3 "), Ok(U64(3))); - - assert_eq!(Json::from_str("-9223372036854775808"), Ok(I64(i64::MIN))); - assert_eq!(Json::from_str("9223372036854775807"), Ok(U64(i64::MAX as u64))); - assert_eq!(Json::from_str("18446744073709551615"), Ok(U64(u64::MAX))); - } - - #[test] - fn test_decode_numbers() { - let v: f64 = super::decode("3").unwrap(); - assert_eq!(v, 3.0); - - let v: f64 = super::decode("3.1").unwrap(); - assert_eq!(v, 3.1); - - let v: f64 = super::decode("-1.2").unwrap(); - assert_eq!(v, -1.2); - - let v: f64 = super::decode("0.4").unwrap(); - assert_eq!(v, 0.4); - - let v: f64 = super::decode("0.4e5").unwrap(); - assert_eq!(v, 0.4e5); - - let v: f64 = super::decode("0.4e15").unwrap(); - assert_eq!(v, 0.4e15); - - let v: f64 = super::decode("0.4e-01").unwrap(); - assert_eq!(v, 0.4e-01); - - let v: f64 = super::decode("123456789.5024").unwrap(); - assert_eq!(v, 123456789.5024); - - let v: u64 = super::decode("0").unwrap(); - assert_eq!(v, 0); - - let v: u64 = super::decode("18446744073709551615").unwrap(); - assert_eq!(v, u64::MAX); - - let v: i64 = super::decode("-9223372036854775808").unwrap(); - assert_eq!(v, i64::MIN); - - let v: i64 = super::decode("9223372036854775807").unwrap(); - assert_eq!(v, i64::MAX); - - let res: DecodeResult = super::decode("765.25252"); - match res { - Ok(..) => panic!("expected an error"), - Err(ExpectedError(ref s, _)) => assert_eq!(s, "Integer"), - Err(..) => panic!("expected an 'expected integer' error"), - } - } - - #[test] - fn test_read_str() { - assert_eq!(Json::from_str("\""), Err(SyntaxError(EOFWhileParsingString, 1, 2))); - assert_eq!(Json::from_str("\"lol"), Err(SyntaxError(EOFWhileParsingString, 1, 5))); - assert_eq!(Json::from_str("\"\n\""), Err(SyntaxError(ControlCharacterInString, 2, 1))); - assert_eq!(Json::from_str("\"\0\""), Err(SyntaxError(ControlCharacterInString, 1, 2))); - assert_eq!(Json::from_str("\"\u{1}\""), Err(SyntaxError(ControlCharacterInString, 1, 2))); - assert_eq!(Json::from_str("\"\u{1F}\""), Err(SyntaxError(ControlCharacterInString, 1, 2))); - - // Only C0 control characters are excluded. - assert!('\u{7F}'.is_control()); - assert!('\u{80}'.is_control()); - assert!('\u{9F}'.is_control()); - let c1_controls = "\u{7F}\u{80}\u{9F}".to_string(); - assert_eq!(Json::from_str(&format!("\"{}\"", c1_controls)), Ok(String(c1_controls))); - - assert_eq!(Json::from_str("\"\""), Ok(String("".to_string()))); - assert_eq!(Json::from_str("\"foo\""), Ok(String("foo".to_string()))); - assert_eq!(Json::from_str("\"\\\"\""), Ok(String("\"".to_string()))); - assert_eq!(Json::from_str("\"\\b\""), Ok(String("\x08".to_string()))); - assert_eq!(Json::from_str("\"\\n\""), Ok(String("\n".to_string()))); - assert_eq!(Json::from_str("\"\\r\""), Ok(String("\r".to_string()))); - assert_eq!(Json::from_str("\"\\t\""), Ok(String("\t".to_string()))); - assert_eq!(Json::from_str(" \"foo\" "), Ok(String("foo".to_string()))); - assert_eq!(Json::from_str("\"\\u12ab\""), Ok(String("\u{12ab}".to_string()))); - assert_eq!(Json::from_str("\"\\uAB12\""), Ok(String("\u{AB12}".to_string()))); - } - - #[test] - fn test_decode_str() { - let s = [("\"\"", ""), - ("\"foo\"", "foo"), - ("\"\\\"\"", "\""), - ("\"\\b\"", "\x08"), - ("\"\\n\"", "\n"), - ("\"\\r\"", "\r"), - ("\"\\t\"", "\t"), - ("\"\\u12ab\"", "\u{12ab}"), - ("\"\\uAB12\"", "\u{AB12}")]; - - for &(i, o) in s.iter() { - let v: string::String = super::decode(i).unwrap(); - assert_eq!(v, o); - } - } - - #[test] - fn test_read_array() { - assert_eq!(Json::from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); - assert_eq!(Json::from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); - assert_eq!(Json::from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); - assert_eq!(Json::from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(Json::from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - - assert_eq!(Json::from_str("[]"), Ok(Array(vec![]))); - assert_eq!(Json::from_str("[ ]"), Ok(Array(vec![]))); - assert_eq!(Json::from_str("[true]"), Ok(Array(vec![Boolean(true)]))); - assert_eq!(Json::from_str("[ false ]"), Ok(Array(vec![Boolean(false)]))); - assert_eq!(Json::from_str("[null]"), Ok(Array(vec![Null]))); - assert_eq!(Json::from_str("[3, 1]"), - Ok(Array(vec![U64(3), U64(1)]))); - assert_eq!(Json::from_str("\n[3, 2]\n"), - Ok(Array(vec![U64(3), U64(2)]))); - assert_eq!(Json::from_str("[2, [4, 1]]"), - Ok(Array(vec![U64(2), Array(vec![U64(4), U64(1)])]))); - } - - #[test] - fn test_decode_array() { - let v: Vec<()> = super::decode("[]").unwrap(); - assert_eq!(v, vec![]); - - let v: Vec<()> = super::decode("[null]").unwrap(); - assert_eq!(v, vec![()]); - - let v: Vec = super::decode("[true]").unwrap(); - assert_eq!(v, vec![true]); - - let v: Vec = super::decode("[3, 1]").unwrap(); - assert_eq!(v, vec![3, 1]); - - let v: Vec> = super::decode("[[3], [1, 2]]").unwrap(); - assert_eq!(v, vec![vec![3], vec![1, 2]]); - } - - #[test] - fn test_decode_tuple() { - let t: (usize, usize, usize) = super::decode("[1, 2, 3]").unwrap(); - assert_eq!(t, (1, 2, 3)); - - let t: (usize, string::String) = super::decode("[1, \"two\"]").unwrap(); - assert_eq!(t, (1, "two".to_string())); - } - - #[test] - fn test_decode_tuple_malformed_types() { - assert!(super::decode::<(usize, string::String)>("[1, 2]").is_err()); - } - - #[test] - fn test_decode_tuple_malformed_length() { - assert!(super::decode::<(usize, usize)>("[1, 2, 3]").is_err()); - } - - #[test] - fn test_read_object() { - assert_eq!(Json::from_str("{"), Err(SyntaxError(EOFWhileParsingObject, 1, 2))); - assert_eq!(Json::from_str("{ "), Err(SyntaxError(EOFWhileParsingObject, 1, 3))); - assert_eq!(Json::from_str("{1"), Err(SyntaxError(KeyMustBeAString, 1, 2))); - assert_eq!(Json::from_str("{ \"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); - assert_eq!(Json::from_str("{\"a\""), Err(SyntaxError(EOFWhileParsingObject, 1, 5))); - assert_eq!(Json::from_str("{\"a\" "), Err(SyntaxError(EOFWhileParsingObject, 1, 6))); - - assert_eq!(Json::from_str("{\"a\" 1"), Err(SyntaxError(ExpectedColon, 1, 6))); - assert_eq!(Json::from_str("{\"a\":"), Err(SyntaxError(EOFWhileParsingValue, 1, 6))); - assert_eq!(Json::from_str("{\"a\":1"), Err(SyntaxError(EOFWhileParsingObject, 1, 7))); - assert_eq!(Json::from_str("{\"a\":1 1"), Err(SyntaxError(InvalidSyntax, 1, 8))); - assert_eq!(Json::from_str("{\"a\":1,"), Err(SyntaxError(EOFWhileParsingObject, 1, 8))); - - assert_eq!(Json::from_str("{}").unwrap(), mk_object(&[])); - assert_eq!(Json::from_str("{\"a\": 3}").unwrap(), - mk_object(&[("a".to_string(), U64(3))])); - - assert_eq!(Json::from_str( - "{ \"a\": null, \"b\" : true }").unwrap(), - mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); - assert_eq!(Json::from_str("\n{ \"a\": null, \"b\" : true }\n").unwrap(), - mk_object(&[ - ("a".to_string(), Null), - ("b".to_string(), Boolean(true))])); - assert_eq!(Json::from_str( - "{\"a\" : 1.0 ,\"b\": [ true ]}").unwrap(), - mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![Boolean(true)])) - ])); - assert_eq!(Json::from_str( - "{\ - \"a\": 1.0, \ - \"b\": [\ - true,\ - \"foo\\nbar\", \ - { \"c\": {\"d\": null} } \ - ]\ - }").unwrap(), - mk_object(&[ - ("a".to_string(), F64(1.0)), - ("b".to_string(), Array(vec![ - Boolean(true), - String("foo\nbar".to_string()), - mk_object(&[ - ("c".to_string(), mk_object(&[("d".to_string(), Null)])) - ]) - ])) - ])); - } - - #[test] - fn test_decode_struct() { - let s = "{ - \"inner\": [ - { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] } - ] - }"; - - let v: Outer = super::decode(s).unwrap(); - assert_eq!( - v, - Outer { - inner: vec![ - Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] } - ] - } - ); - } - - #[derive(RustcDecodable)] - struct FloatStruct { - f: f64, - a: Vec - } - #[test] - fn test_decode_struct_with_nan() { - let s = "{\"f\":null,\"a\":[null,123]}"; - let obj: FloatStruct = super::decode(s).unwrap(); - assert!(obj.f.is_nan()); - assert!(obj.a[0].is_nan()); - assert_eq!(obj.a[1], 123f64); - } - - #[test] - fn test_decode_option() { - let value: Option = super::decode("null").unwrap(); - assert_eq!(value, None); - - let value: Option = super::decode("\"jodhpurs\"").unwrap(); - assert_eq!(value, Some("jodhpurs".to_string())); - } - - #[test] - fn test_decode_enum() { - let value: Animal = super::decode("\"Dog\"").unwrap(); - assert_eq!(value, Dog); - - let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}"; - let value: Animal = super::decode(s).unwrap(); - assert_eq!(value, Frog("Henry".to_string(), 349)); - } - - #[test] - fn test_decode_result() { - let value: Result = Ok(4); - let json_value = super::encode(&value).unwrap(); - assert_eq!(json_value, "{\"variant\":\"Ok\",\"fields\":[4]}"); - let decoded_value: Result = super::decode(&json_value).unwrap(); - assert_eq!(decoded_value, Ok(4)); - } - - #[test] - fn test_decode_map() { - let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\ - \"fields\":[\"Henry\", 349]}}"; - let mut map: BTreeMap = super::decode(s).unwrap(); - - assert_eq!(map.remove(&"a".to_string()), Some(Dog)); - assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); - } - - #[test] - fn test_multiline_errors() { - assert_eq!(Json::from_str("{\n \"foo\":\n \"bar\""), - Err(SyntaxError(EOFWhileParsingObject, 3, 8))); - } - - #[derive(RustcDecodable)] - #[allow(dead_code)] - struct DecodeStruct { - x: f64, - y: bool, - z: string::String, - w: Vec - } - #[derive(RustcDecodable)] - enum DecodeEnum { - A(f64), - B(string::String) - } - fn check_err(to_parse: &'static str, expected: DecoderError) { - let res: DecodeResult = match Json::from_str(to_parse) { - Err(e) => Err(ParseError(e)), - Ok(json) => Decodable::decode(&mut Decoder::new(json)) - }; - match res { - Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", - to_parse, expected), - Err(ParseError(e)) => panic!("`{}` is not valid json: {:?}", - to_parse, e), - Err(e) => { - assert_eq!(e, expected); - } - } - } - #[test] - fn test_decode_errors_struct() { - check_err::("[]", ExpectedError("Object".to_string(), "[]".to_string())); - check_err::("{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}", - ExpectedError("Number".to_string(), "true".to_string())); - check_err::("{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}", - ExpectedError("Boolean".to_string(), "[]".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}", - ExpectedError("String".to_string(), "{}".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}", - ExpectedError("Array".to_string(), "null".to_string())); - check_err::("{\"x\": 1, \"y\": true, \"z\": \"\"}", - MissingFieldError("w".to_string())); - } - #[test] - fn test_decode_errors_enum() { - check_err::("{}", - MissingFieldError("variant".to_string())); - check_err::("{\"variant\": 1}", - ExpectedError("String".to_string(), "1".to_string())); - check_err::("{\"variant\": \"A\"}", - MissingFieldError("fields".to_string())); - check_err::("{\"variant\": \"A\", \"fields\": null}", - ExpectedError("Array".to_string(), "null".to_string())); - check_err::("{\"variant\": \"C\", \"fields\": []}", - UnknownVariantError("C".to_string())); - } - - #[test] - fn test_find(){ - let json_value = Json::from_str("{\"dog\" : \"cat\"}").unwrap(); - let found_str = json_value.find("dog"); - assert!(found_str.unwrap().as_string().unwrap() == "cat"); - } - - #[test] - fn test_find_path(){ - let json_value = Json::from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.find_path(&["dog", "cat", "mouse"]); - assert!(found_str.unwrap().as_string().unwrap() == "cheese"); - } - - #[test] - fn test_search(){ - let json_value = Json::from_str("{\"dog\":{\"cat\": {\"mouse\" : \"cheese\"}}}").unwrap(); - let found_str = json_value.search("mouse").and_then(|j| j.as_string()); - assert!(found_str.unwrap() == "cheese"); - } - - #[test] - fn test_index(){ - let json_value = Json::from_str("{\"animals\":[\"dog\",\"cat\",\"mouse\"]}").unwrap(); - let ref array = json_value["animals"]; - assert_eq!(array[0].as_string().unwrap(), "dog"); - assert_eq!(array[1].as_string().unwrap(), "cat"); - assert_eq!(array[2].as_string().unwrap(), "mouse"); - } - - #[test] - fn test_is_object(){ - let json_value = Json::from_str("{}").unwrap(); - assert!(json_value.is_object()); - } - - #[test] - fn test_as_object(){ - let json_value = Json::from_str("{}").unwrap(); - let json_object = json_value.as_object(); - assert!(json_object.is_some()); - } - - #[test] - fn test_is_array(){ - let json_value = Json::from_str("[1, 2, 3]").unwrap(); - assert!(json_value.is_array()); - } - - #[test] - fn test_as_array(){ - let json_value = Json::from_str("[1, 2, 3]").unwrap(); - let json_array = json_value.as_array(); - let expected_length = 3; - assert!(json_array.is_some() && json_array.unwrap().len() == expected_length); - } - - #[test] - fn test_is_string(){ - let json_value = Json::from_str("\"dog\"").unwrap(); - assert!(json_value.is_string()); - } - - #[test] - fn test_as_string(){ - let json_value = Json::from_str("\"dog\"").unwrap(); - let json_str = json_value.as_string(); - let expected_str = "dog"; - assert_eq!(json_str, Some(expected_str)); - } - - #[test] - fn test_is_number(){ - let json_value = Json::from_str("12").unwrap(); - assert!(json_value.is_number()); - } - - #[test] - fn test_is_i64(){ - let json_value = Json::from_str("-12").unwrap(); - assert!(json_value.is_i64()); - - let json_value = Json::from_str("12").unwrap(); - assert!(!json_value.is_i64()); - - let json_value = Json::from_str("12.0").unwrap(); - assert!(!json_value.is_i64()); - } - - #[test] - fn test_is_u64(){ - let json_value = Json::from_str("12").unwrap(); - assert!(json_value.is_u64()); - - let json_value = Json::from_str("-12").unwrap(); - assert!(!json_value.is_u64()); - - let json_value = Json::from_str("12.0").unwrap(); - assert!(!json_value.is_u64()); - } - - #[test] - fn test_is_f64(){ - let json_value = Json::from_str("12").unwrap(); - assert!(!json_value.is_f64()); - - let json_value = Json::from_str("-12").unwrap(); - assert!(!json_value.is_f64()); - - let json_value = Json::from_str("12.0").unwrap(); - assert!(json_value.is_f64()); - - let json_value = Json::from_str("-12.0").unwrap(); - assert!(json_value.is_f64()); - } - - #[test] - fn test_as_i64(){ - let json_value = Json::from_str("-12").unwrap(); - let json_num = json_value.as_i64(); - assert_eq!(json_num, Some(-12)); - } - - #[test] - fn test_as_u64(){ - let json_value = Json::from_str("12").unwrap(); - let json_num = json_value.as_u64(); - assert_eq!(json_num, Some(12)); - } - - #[test] - fn test_as_f64(){ - let json_value = Json::from_str("12.0").unwrap(); - let json_num = json_value.as_f64(); - assert_eq!(json_num, Some(12f64)); - } - - #[test] - fn test_is_boolean(){ - let json_value = Json::from_str("false").unwrap(); - assert!(json_value.is_boolean()); - } - - #[test] - fn test_as_boolean(){ - let json_value = Json::from_str("false").unwrap(); - let json_bool = json_value.as_boolean(); - let expected_bool = false; - assert!(json_bool.is_some() && json_bool.unwrap() == expected_bool); - } - - #[test] - fn test_is_null(){ - let json_value = Json::from_str("null").unwrap(); - assert!(json_value.is_null()); - } - - #[test] - fn test_as_null(){ - let json_value = Json::from_str("null").unwrap(); - let json_null = json_value.as_null(); - let expected_null = (); - assert!(json_null.is_some() && json_null.unwrap() == expected_null); - } - - #[test] - fn test_encode_hashmap_with_numeric_key() { - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let json_str = super::as_pretty_json(&hm).to_string(); - match Json::from_str(&json_str) { - Err(_) => panic!("Unable to parse json_str: {}", json_str), - _ => {} // it parsed and we are good to go - } - } - - #[test] - fn test_negative_zero() { - Json::from_str("{\"test\":-0}").unwrap(); - } - - #[test] - fn test_prettyencode_hashmap_with_numeric_key() { - use std::collections::HashMap; - let mut hm: HashMap = HashMap::new(); - hm.insert(1, true); - let json_str = super::as_pretty_json(&hm).to_string(); - match Json::from_str(&json_str) { - Err(_) => panic!("Unable to parse json_str: {}", json_str), - _ => {} // it parsed and we are good to go - } - } - - #[test] - fn test_prettyencoder_indent_level_param() { - use std::collections::BTreeMap; - - let mut tree = BTreeMap::new(); - - tree.insert("hello".to_string(), String("guten tag".to_string())); - tree.insert("goodbye".to_string(), String("sayonara".to_string())); - - let json = Array( - // The following layout below should look a lot like - // the pretty-printed JSON (indent * x) - vec! - ( // 0x - String("greetings".to_string()), // 1x - Object(tree), // 1x + 2x + 2x + 1x - ) // 0x - // End JSON array (7 lines) - ); - - // Helper function for counting indents - fn indents(source: &str) -> usize { - let trimmed = source.trim_left_matches(' '); - source.len() - trimmed.len() - } - - // Test up to 4 spaces of indents (more?) - for i in 0..4 { - let printed = super::as_pretty_json(&json).indent(i as u32) - .to_string(); - - // Check for indents at each line - let lines: Vec<&str> = printed.lines().collect(); - assert_eq!(lines.len(), 7); // JSON should be 7 lines - - assert_eq!(indents(lines[0]), 0 * i); // [ - assert_eq!(indents(lines[1]), 1 * i); // "greetings", - assert_eq!(indents(lines[2]), 1 * i); // { - assert_eq!(indents(lines[3]), 2 * i); // "hello": "guten tag", - assert_eq!(indents(lines[4]), 2 * i); // "goodbye": "sayonara" - assert_eq!(indents(lines[5]), 1 * i); // }, - assert_eq!(indents(lines[6]), 0 * i); // ] - - // Finally, test that the pretty-printed JSON is valid - Json::from_str(&printed).ok() - .expect("Pretty-printed JSON is invalid!"); - } - } - - #[test] - fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() { - use std::collections::HashMap; - use Decodable; - let json_str = "{\"1\":true}"; - let json_obj = match Json::from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {}", json_str), - Ok(o) => o - }; - let mut decoder = Decoder::new(json_obj); - let _hm: HashMap = Decodable::decode(&mut decoder).unwrap(); - } - - #[test] - fn test_hashmap_with_enum_key() { - use std::collections::HashMap; - use json; - #[derive(RustcEncodable, Eq, Hash, PartialEq, RustcDecodable, Debug)] - enum Enum { - Foo, - #[allow(dead_code)] - Bar, - } - let mut map = HashMap::new(); - map.insert(Enum::Foo, 0); - let result = json::encode(&map).unwrap(); - assert_eq!(result, r#"{"Foo":0}"#); - let decoded: HashMap = json::decode(&result).unwrap(); - assert_eq!(map, decoded); - } - - #[test] - fn test_hashmap_with_numeric_key_will_error_with_string_keys() { - use std::collections::HashMap; - use Decodable; - let json_str = "{\"a\":true}"; - let json_obj = match Json::from_str(json_str) { - Err(_) => panic!("Unable to parse json_str: {}", json_str), - Ok(o) => o - }; - let mut decoder = Decoder::new(json_obj); - let result: Result, DecoderError> = Decodable::decode(&mut decoder); - assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string()))); - } - - fn assert_stream_equal(src: &str, - expected: Vec<(JsonEvent, Vec)>) { - let mut parser = Parser::new(src.chars()); - let mut i = 0; - loop { - let evt = match parser.next() { - Some(e) => e, - None => { break; } - }; - let (ref expected_evt, ref expected_stack) = expected[i]; - if !parser.stack().is_equal_to(&expected_stack) { - panic!("Parser stack is not equal to {:?}", expected_stack); - } - assert_eq!(&evt, expected_evt); - i+=1; - } - } - #[test] - #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) - fn test_streaming_parser() { - assert_stream_equal( - r#"{ "foo":"bar", "array" : [0, 1, 2, 3, 4, 5], "idents":[null,true,false]}"#, - vec![ - (ObjectStart, vec![]), - (StringValue("bar".to_string()), vec![Key("foo")]), - (ArrayStart, vec![Key("array")]), - (U64Value(0), vec![Key("array"), Index(0)]), - (U64Value(1), vec![Key("array"), Index(1)]), - (U64Value(2), vec![Key("array"), Index(2)]), - (U64Value(3), vec![Key("array"), Index(3)]), - (U64Value(4), vec![Key("array"), Index(4)]), - (U64Value(5), vec![Key("array"), Index(5)]), - (ArrayEnd, vec![Key("array")]), - (ArrayStart, vec![Key("idents")]), - (NullValue, vec![Key("idents"), Index(0)]), - (BooleanValue(true), vec![Key("idents"), Index(1)]), - (BooleanValue(false), vec![Key("idents"), Index(2)]), - (ArrayEnd, vec![Key("idents")]), - (ObjectEnd, vec![]), - ] - ); - } - fn last_event(src: &str) -> JsonEvent { - let mut parser = Parser::new(src.chars()); - let mut evt = NullValue; - loop { - evt = match parser.next() { - Some(e) => e, - None => return evt, - } - } - } - - #[test] - #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) - fn test_read_object_streaming() { - assert_eq!(last_event("{ "), Error(SyntaxError(EOFWhileParsingObject, 1, 3))); - assert_eq!(last_event("{1"), Error(SyntaxError(KeyMustBeAString, 1, 2))); - assert_eq!(last_event("{ \"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - assert_eq!(last_event("{\"a\""), Error(SyntaxError(EOFWhileParsingObject, 1, 5))); - assert_eq!(last_event("{\"a\" "), Error(SyntaxError(EOFWhileParsingObject, 1, 6))); - - assert_eq!(last_event("{\"a\" 1"), Error(SyntaxError(ExpectedColon, 1, 6))); - assert_eq!(last_event("{\"a\":"), Error(SyntaxError(EOFWhileParsingValue, 1, 6))); - assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7))); - assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8))); - assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8))); - assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8))); - - assert_stream_equal( - "{}", - vec![(ObjectStart, vec![]), (ObjectEnd, vec![])] - ); - assert_stream_equal( - "{\"a\": 3}", - vec![ - (ObjectStart, vec![]), - (U64Value(3), vec![Key("a")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - "{ \"a\": null, \"b\" : true }", - vec![ - (ObjectStart, vec![]), - (NullValue, vec![Key("a")]), - (BooleanValue(true), vec![Key("b")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - "{\"a\" : 1.0 ,\"b\": [ true ]}", - vec![ - (ObjectStart, vec![]), - (F64Value(1.0), vec![Key("a")]), - (ArrayStart, vec![Key("b")]), - (BooleanValue(true),vec![Key("b"), Index(0)]), - (ArrayEnd, vec![Key("b")]), - (ObjectEnd, vec![]), - ] - ); - assert_stream_equal( - r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} }, - "\uD834\uDF06" - ] - }"#, - vec![ - (ObjectStart, vec![]), - (F64Value(1.0), vec![Key("a")]), - (ArrayStart, vec![Key("b")]), - (BooleanValue(true), vec![Key("b"), Index(0)]), - (StringValue("foo\nbar".to_string()), vec![Key("b"), Index(1)]), - (ObjectStart, vec![Key("b"), Index(2)]), - (ObjectStart, vec![Key("b"), Index(2), Key("c")]), - (NullValue, vec![Key("b"), Index(2), Key("c"), Key("d")]), - (ObjectEnd, vec![Key("b"), Index(2), Key("c")]), - (ObjectEnd, vec![Key("b"), Index(2)]), - (StringValue("\u{1D306}".to_string()), vec![Key("b"), Index(3)]), - (ArrayEnd, vec![Key("b")]), - (ObjectEnd, vec![]), - ] - ); - } - #[test] - #[cfg_attr(target_word_size = "32", ignore)] // FIXME(#14064) - fn test_read_array_streaming() { - assert_stream_equal( - "[]", - vec![ - (ArrayStart, vec![]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[ ]", - vec![ - (ArrayStart, vec![]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[true]", - vec![ - (ArrayStart, vec![]), - (BooleanValue(true), vec![Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[ false ]", - vec![ - (ArrayStart, vec![]), - (BooleanValue(false), vec![Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[null]", - vec![ - (ArrayStart, vec![]), - (NullValue, vec![Index(0)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[3, 1]", - vec![ - (ArrayStart, vec![]), - (U64Value(3), vec![Index(0)]), - (U64Value(1), vec![Index(1)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "\n[3, 2]\n", - vec![ - (ArrayStart, vec![]), - (U64Value(3), vec![Index(0)]), - (U64Value(2), vec![Index(1)]), - (ArrayEnd, vec![]), - ] - ); - assert_stream_equal( - "[2, [4, 1]]", - vec![ - (ArrayStart, vec![]), - (U64Value(2), vec![Index(0)]), - (ArrayStart, vec![Index(1)]), - (U64Value(4), vec![Index(1), Index(0)]), - (U64Value(1), vec![Index(1), Index(1)]), - (ArrayEnd, vec![Index(1)]), - (ArrayEnd, vec![]), - ] - ); - - assert_eq!(last_event("["), Error(SyntaxError(EOFWhileParsingValue, 1, 2))); - - assert_eq!(Json::from_str("["), Err(SyntaxError(EOFWhileParsingValue, 1, 2))); - assert_eq!(Json::from_str("[1"), Err(SyntaxError(EOFWhileParsingArray, 1, 3))); - assert_eq!(Json::from_str("[1,"), Err(SyntaxError(EOFWhileParsingValue, 1, 4))); - assert_eq!(Json::from_str("[1,]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(Json::from_str("[6 7]"), Err(SyntaxError(InvalidSyntax, 1, 4))); - - } - #[test] - fn test_trailing_characters_streaming() { - assert_eq!(last_event("nulla"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("truea"), Error(SyntaxError(TrailingCharacters, 1, 5))); - assert_eq!(last_event("falsea"), Error(SyntaxError(TrailingCharacters, 1, 6))); - assert_eq!(last_event("1a"), Error(SyntaxError(TrailingCharacters, 1, 2))); - assert_eq!(last_event("[]a"), Error(SyntaxError(TrailingCharacters, 1, 3))); - assert_eq!(last_event("{}a"), Error(SyntaxError(TrailingCharacters, 1, 3))); - } - #[test] - fn test_read_identifiers_streaming() { - assert_eq!(Parser::new("null".chars()).next(), Some(NullValue)); - assert_eq!(Parser::new("true".chars()).next(), Some(BooleanValue(true))); - assert_eq!(Parser::new("false".chars()).next(), Some(BooleanValue(false))); - - assert_eq!(last_event("n"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("nul"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("t"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("truz"), Error(SyntaxError(InvalidSyntax, 1, 4))); - assert_eq!(last_event("f"), Error(SyntaxError(InvalidSyntax, 1, 2))); - assert_eq!(last_event("faz"), Error(SyntaxError(InvalidSyntax, 1, 3))); - } - - #[test] - fn test_stack() { - let mut stack = Stack::new(); - - assert!(stack.is_empty()); - assert!(stack.len() == 0); - assert!(!stack.last_is_index()); - - stack.push_index(0); - stack.bump_index(); - - assert!(stack.len() == 1); - assert!(stack.is_equal_to(&[Index(1)])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1)])); - assert!(stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - - stack.push_key("foo".to_string()); - - assert!(stack.len() == 2); - assert!(stack.is_equal_to(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1), Key("foo")])); - assert!(stack.ends_with(&[Key("foo")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); - - stack.push_key("bar".to_string()); - - assert!(stack.len() == 3); - assert!(stack.is_equal_to(&[Index(1), Key("foo"), Key("bar")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo"), Key("bar")])); - assert!(stack.ends_with(&[Key("bar")])); - assert!(stack.ends_with(&[Key("foo"), Key("bar")])); - assert!(stack.ends_with(&[Index(1), Key("foo"), Key("bar")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); - assert!(stack.get(2) == Key("bar")); - - stack.pop(); - - assert!(stack.len() == 2); - assert!(stack.is_equal_to(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1), Key("foo")])); - assert!(stack.starts_with(&[Index(1)])); - assert!(stack.ends_with(&[Index(1), Key("foo")])); - assert!(stack.ends_with(&[Key("foo")])); - assert!(!stack.last_is_index()); - assert!(stack.get(0) == Index(1)); - assert!(stack.get(1) == Key("foo")); - } - - #[test] - fn test_to_json() { - use std::collections::{HashMap,BTreeMap}; - use super::ToJson; - - let array2 = Array(vec!(I64(1), I64(2))); - let array3 = Array(vec!(I64(1), I64(2), I64(3))); - let object = { - let mut tree_map = BTreeMap::new(); - tree_map.insert("a".to_string(), U64(1)); - tree_map.insert("b".to_string(), U64(2)); - Object(tree_map) - }; - - assert_eq!(array2.to_json(), array2); - assert_eq!(object.to_json(), object); - assert_eq!(3_isize.to_json(), I64(3)); - assert_eq!(4_i8.to_json(), I64(4)); - assert_eq!(5_i16.to_json(), I64(5)); - assert_eq!(6_i32.to_json(), I64(6)); - assert_eq!(7_i64.to_json(), I64(7)); - assert_eq!(8_usize.to_json(), U64(8)); - assert_eq!(9_u8.to_json(), U64(9)); - assert_eq!(10_u16.to_json(), U64(10)); - assert_eq!(11_u32.to_json(), U64(11)); - assert_eq!(12_u64.to_json(), U64(12)); - assert_eq!(13.0_f32.to_json(), F64(13.0_f64)); - assert_eq!(14.0_f64.to_json(), F64(14.0_f64)); - assert_eq!(().to_json(), Null); - assert_eq!(f32::INFINITY.to_json(), Null); - assert_eq!(f64::NAN.to_json(), Null); - assert_eq!(true.to_json(), Boolean(true)); - assert_eq!(false.to_json(), Boolean(false)); - assert_eq!("abc".to_json(), String("abc".to_string())); - assert_eq!("abc".to_string().to_json(), String("abc".to_string())); - assert_eq!((1, 2).to_json(), array2); - assert_eq!((1, 2, 3).to_json(), array3); - assert_eq!([1, 2].to_json(), array2); - assert_eq!((&[1, 2, 3]).to_json(), array3); - assert_eq!((vec![1, 2]).to_json(), array2); - assert_eq!(vec!(1, 2, 3).to_json(), array3); - let mut tree_map = BTreeMap::new(); - tree_map.insert("a".to_string(), 1 as u32); - tree_map.insert("b".to_string(), 2); - assert_eq!(tree_map.to_json(), object); - let mut hash_map = HashMap::new(); - hash_map.insert("a".to_string(), 1 as u32); - hash_map.insert("b".to_string(), 2); - assert_eq!(hash_map.to_json(), object); - assert_eq!(Some(15).to_json(), I64(15)); - assert_eq!(Some(15 as u32).to_json(), U64(15)); - assert_eq!(None::.to_json(), Null); - } - - #[test] - fn test_encode_hashmap_with_arbitrary_key() { - use std::collections::HashMap; - #[derive(PartialEq, Eq, Hash, RustcEncodable)] - struct ArbitraryType(u32); - let mut hm: HashMap = HashMap::new(); - hm.insert(ArbitraryType(1), true); - let mut mem_buf = string::String::new(); - let mut encoder = Encoder::new(&mut mem_buf); - let result = hm.encode(&mut encoder); - match result.err().unwrap() { - EncoderError::BadHashmapKey => (), - _ => panic!("expected bad hash map key") - } - } - - #[test] - fn test_encode_decode_phantom_data() { - use std::marker::PhantomData; - - #[derive(Debug, RustcDecodable, RustcEncodable, Eq, PartialEq)] - struct Foo

{ - phantom_data: PhantomData

- } - - let f: Foo = Foo { - phantom_data: PhantomData - }; - let s = super::encode(&f).unwrap(); - let d: Foo = super::decode(&s).unwrap(); - assert_eq!(f, d); - } - - #[test] - fn test_bad_json_stack_depleted() { - use json; - #[derive(Debug, RustcDecodable)] - enum ChatEvent { - Variant(i32) - } - let serialized = "{\"variant\": \"Variant\", \"fields\": []}"; - let r: Result = json::decode(serialized); - assert!(r.unwrap_err() == EOF); - } - - #[test] - fn fixed_length_array() { - #[derive(Debug, RustcDecodable, RustcEncodable, Eq, PartialEq)] - struct Foo { - a: [u8; 1], - b: [i32; 2], - c: [u64; 3], - } - let f = Foo { - a: [0], - b: [1, 2], - c: [3, 4, 5], - }; - let s = super::encode(&f).unwrap(); - let d = super::decode(&s).unwrap(); - assert_eq!(f, d); - } - - #[test] - fn test_unexpected_token() { - match Json::from_str("{\"\":\"\",\"\":{\"\":\"\",\"\":[{\"\":\"\",}}}") { - Err(e) => assert_eq!(e, SyntaxError(InvalidSyntax, 1, 32)), - _ => () - }; - } -} diff --git a/third_party/rust/rustc-serialize/src/lib.rs b/third_party/rust/rustc-serialize/src/lib.rs deleted file mode 100644 index 8b0fb22f2749..000000000000 --- a/third_party/rust/rustc-serialize/src/lib.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Support code for encoding and decoding types. -//! -//! > **NOTE**: This crate is deprecated in favor of [`serde`]. No new feature -//! > development will happen in this crate, although bug fixes proposed through -//! > PRs will still be merged. It is very highly recommended by the Rust -//! > Library Team that you use [`serde`], not this crate. -//! -//! [`serde`]: https://serde.rs -//! -//! # Usage -//! -//! This crate is [on crates.io](https://crates.io/crates/rustc-serialize) and -//! can be used by adding `rustc-serialize` to the dependencies in your -//! project's `Cargo.toml`. -//! -//! ```toml -//! [dependencies] -//! rustc-serialize = "0.3" -//! ``` -//! -//! and this to your crate root: -//! -//! ```rust -//! extern crate rustc_serialize; -//! ``` - -#![cfg_attr(rustbuild, feature(staged_api, rustc_private))] -#![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] - -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/rustc-serialize/")] -#![cfg_attr(test, deny(warnings))] -#![allow(trivial_numeric_casts)] -#![cfg_attr(rust_build, feature(staged_api))] -#![cfg_attr(rust_build, staged_api)] -#![cfg_attr(rust_build, - unstable(feature = "rustc_private", - reason = "use the crates.io `rustc-serialize` library instead"))] - -#[cfg(test)] extern crate rand; - -pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, - DecoderHelpers, EncoderHelpers}; - - -// Limit collections from allocating more than -// 1 MB for calls to `with_capacity`. -fn cap_capacity(given_len: usize) -> usize { - use std::cmp::min; - use std::mem::size_of; - const PRE_ALLOCATE_CAP: usize = 0x100000; - - match size_of::() { - 0 => min(given_len, PRE_ALLOCATE_CAP), - n => min(given_len, PRE_ALLOCATE_CAP / n) - } -} - -mod serialize; -mod collection_impls; - -pub mod base64; -pub mod hex; -pub mod json; - -mod rustc_serialize { - pub use serialize::*; -} diff --git a/third_party/rust/rustc-serialize/src/serialize.rs b/third_party/rust/rustc-serialize/src/serialize.rs deleted file mode 100644 index 296f3d48e004..000000000000 --- a/third_party/rust/rustc-serialize/src/serialize.rs +++ /dev/null @@ -1,1671 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Support code for encoding and decoding types. -//! -//! In order to allow extensibility in both what types can be encoded and how -//! they are encoded, encoding and decoding are split into two part each. An -//! implementation of the Encodable trait knows how to turn a specific type into -//! a generic form, and then uses an implementation of the Encoder trait to turn -//! this into concrete output (such as a JSON string). Decoder and Decodable do -//! the same for decoding. - -/* -Core encoding and decoding interfaces. -*/ - -use std::cell::{Cell, RefCell}; -use std::ffi::OsString; -use std::path; -use std::rc::Rc; -use std::sync::Arc; -use std::marker::PhantomData; -use std::borrow::Cow; - -use cap_capacity; - -/// Trait for writing out an encoding when serializing. -/// -/// This trait provides methods to encode basic types and generic forms of -/// collections. Implementations of `Encodable` use it to perform the actual -/// encoding of a type. -/// -/// It is unspecified what is done with the encoding - it could be stored in a -/// variable, or written directly to a file, for example. -/// -/// Encoders can expect to only have a single "root" method call made on this -/// trait. Non-trivial types will call one of the collection-emitting methods, -/// passing a function that may call other methods on the trait, but once the -/// collection-emitting method has returned, encoding should be complete. -pub trait Encoder { - /// The error type for method results. - type Error; - - // Primitive types: - /// Emit a nil value. - /// - /// For example, this might be stored as the null keyword in JSON. - fn emit_nil(&mut self) -> Result<(), Self::Error>; - - /// Emit a usize value. - fn emit_usize(&mut self, v: usize) -> Result<(), Self::Error>; - - /// Emit a u64 value. - fn emit_u64(&mut self, v: u64) -> Result<(), Self::Error>; - - /// Emit a u32 value. - fn emit_u32(&mut self, v: u32) -> Result<(), Self::Error>; - - /// Emit a u16 value. - fn emit_u16(&mut self, v: u16) -> Result<(), Self::Error>; - - /// Emit a u8 value. - fn emit_u8(&mut self, v: u8) -> Result<(), Self::Error>; - - /// Emit a isize value. - fn emit_isize(&mut self, v: isize) -> Result<(), Self::Error>; - - /// Emit a i64 value. - fn emit_i64(&mut self, v: i64) -> Result<(), Self::Error>; - - /// Emit a i32 value. - fn emit_i32(&mut self, v: i32) -> Result<(), Self::Error>; - - /// Emit a i16 value. - fn emit_i16(&mut self, v: i16) -> Result<(), Self::Error>; - - /// Emit a i8 value. - fn emit_i8(&mut self, v: i8) -> Result<(), Self::Error>; - - /// Emit a bool value. - /// - /// For example, this might be stored as the true and false keywords in - /// JSON. - fn emit_bool(&mut self, v: bool) -> Result<(), Self::Error>; - - /// Emit a f64 value. - fn emit_f64(&mut self, v: f64) -> Result<(), Self::Error>; - - /// Emit a f32 value. - fn emit_f32(&mut self, v: f32) -> Result<(), Self::Error>; - - /// Emit a char value. - /// - /// Note that strings should be emitted using `emit_str`, not as a sequence - /// of `emit_char` calls. - fn emit_char(&mut self, v: char) -> Result<(), Self::Error>; - - /// Emit a string value. - fn emit_str(&mut self, v: &str) -> Result<(), Self::Error>; - - // Compound types: - /// Emit an enumeration value. - /// - /// * `name` indicates the enumeration type name. - /// * `f` is a function that will call `emit_enum_variant` or - /// `emit_enum_struct_variant` as appropriate to write the actual value. - fn emit_enum(&mut self, name: &str, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a enumeration variant value with no or unnamed data. - /// - /// This should only be called from a function passed to `emit_enum`. - /// Variants with named data should use `emit_enum_struct_variant`. - /// - /// * `v_name` is the variant name - /// * `v_id` is the numeric identifier for the variant. - /// * `len` is the number of data items associated with the variant. - /// * `f` is a function that will call `emit_enum_variant_arg` for each data - /// item. It may not be called if len is 0. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// - /// enum Message { - /// Quit, - /// ChangeColor(i32, i32, i32), - /// } - /// - /// impl Encodable for Message { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// s.emit_enum("Message", |s| { - /// match *self { - /// Message::Quit => { - /// s.emit_enum_variant("Quit", 0, 0, |s| Ok(())) - /// } - /// Message::ChangeColor(r, g, b) => { - /// s.emit_enum_variant("ChangeColor", 1, 3, |s| { - /// try!(s.emit_enum_variant_arg(0, |s| { - /// s.emit_i32(r) - /// })); - /// try!(s.emit_enum_variant_arg(1, |s| { - /// s.emit_i32(g) - /// })); - /// try!(s.emit_enum_variant_arg(2, |s| { - /// s.emit_i32(b) - /// })); - /// Ok(()) - /// }) - /// } - /// } - /// }) - /// } - /// } - /// ``` - fn emit_enum_variant(&mut self, v_name: &str, - v_id: usize, - len: usize, - f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit an unnamed data item for an enumeration variant. - /// - /// This should only be called from a function passed to - /// `emit_enum_variant`. - /// - /// * `a_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that variant data items must be emitted in order - starting with - /// index `0` and finishing with index `len-1`. - fn emit_enum_variant_arg(&mut self, a_idx: usize, f: F) - -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a enumeration variant value with no or named data. - /// - /// This should only be called from a function passed to `emit_enum`. - /// Variants with unnamed data should use `emit_enum_variant`. - /// - /// * `v_name` is the variant name. - /// * `v_id` is the numeric identifier for the variant. - /// * `len` is the number of data items associated with the variant. - /// * `f` is a function that will call `emit_enum_struct_variant_field` for - /// each data item. It may not be called if `len` is `0`. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// - /// enum Message { - /// Quit, - /// Move { x: i32, y: i32 }, - /// } - /// - /// impl Encodable for Message { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// s.emit_enum("Message", |s| { - /// match *self { - /// Message::Quit => { - /// s.emit_enum_struct_variant("Quit", 0, 0, |s| Ok(())) - /// } - /// Message::Move { x: x, y: y } => { - /// s.emit_enum_struct_variant("Move", 1, 2, |s| { - /// try!(s.emit_enum_struct_variant_field("x", 0, |s| { - /// s.emit_i32(x) - /// })); - /// try!(s.emit_enum_struct_variant_field("y", 1, |s| { - /// s.emit_i32(y) - /// })); - /// Ok(()) - /// }) - /// } - /// } - /// }) - /// } - /// } - /// ``` - fn emit_enum_struct_variant(&mut self, v_name: &str, - v_id: usize, - len: usize, - f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a named data item for an enumeration variant. - /// - /// This should only be called from a function passed to - /// `emit_enum_struct_variant`. - /// - /// * `f_name` is the name of the data item field. - /// * `f_idx` is its (zero-based) index. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that fields must be emitted in order - starting with index `0` and - /// finishing with index `len-1`. - fn emit_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: usize, - f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a struct value. - /// - /// * `name` is the name of the struct. - /// * `len` is the number of members. - /// * `f` is a function that calls `emit_struct_field` for each member. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// - /// struct Point { - /// x: i32, - /// y: i32, - /// } - /// - /// impl Encodable for Point { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// s.emit_struct("Point", 2, |s| { - /// try!(s.emit_struct_field("x", 0, |s| { - /// s.emit_i32(self.x) - /// })); - /// try!(s.emit_struct_field("y", 1, |s| { - /// s.emit_i32(self.y) - /// })); - /// Ok(()) - /// }) - /// } - /// } - /// ``` - fn emit_struct(&mut self, name: &str, len: usize, f: F) - -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - /// Emit a field item for a struct. - /// - /// This should only be called from a function passed to `emit_struct`. - /// - /// * `f_name` is the name of the data item field. - /// * `f_idx` is its (zero-based) index. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that fields must be emitted in order - starting with index `0` and - /// finishing with index `len-1`. - fn emit_struct_field(&mut self, f_name: &str, f_idx: usize, f: F) - -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a tuple value. - /// - /// * `len` is the number of items in the tuple. - /// * `f` is a function that calls `emit_tuple_arg` for each member. - /// - /// Note that external `Encodable` implementations should not normally need - /// to use this method directly; it is meant for the use of this module's - /// own implementation of `Encodable` for tuples. - fn emit_tuple(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a data item for a tuple. - /// - /// This should only be called from a function passed to `emit_tuple`. - /// - /// * `idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that tuple items must be emitted in order - starting with index `0` - /// and finishing with index `len-1`. - fn emit_tuple_arg(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a tuple struct value. - /// - /// * `name` is the name of the tuple struct. - /// * `len` is the number of items in the tuple struct. - /// * `f` is a function that calls `emit_tuple_struct_arg` for each member. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// - /// struct Pair(i32,i32); - /// - /// impl Encodable for Pair { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// let Pair(first,second) = *self; - /// s.emit_tuple_struct("Pair", 2, |s| { - /// try!(s.emit_tuple_arg(0, |s| { - /// s.emit_i32(first) - /// })); - /// try!(s.emit_tuple_arg(1, |s| { - /// s.emit_i32(second) - /// })); - /// Ok(()) - /// }) - /// } - /// } - /// ``` - fn emit_tuple_struct(&mut self, name: &str, len: usize, f: F) - -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a data item for a tuple struct. - /// - /// This should only be called from a function passed to - /// `emit_tuple_struct`. - /// - /// * `f_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that tuple items must be emitted in order - starting with index `0` - /// and finishing with index `len-1`. - fn emit_tuple_struct_arg(&mut self, f_idx: usize, f: F) - -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - // Specialized types: - /// Emit an optional value. - /// - /// `f` is a function that will call either `emit_option_none` or - /// `emit_option_some` as appropriate. - /// - /// This method allows encoders to handle `Option` values specially, - /// rather than using the generic enum methods, because many encoding - /// formats have a built-in "optional" concept. - /// - /// Note that external `Encodable` implementations should not normally need - /// to use this method directly; it is meant for the use of this module's - /// own implementation of `Encodable` for `Option`. - fn emit_option(&mut self, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit the `None` optional value. - /// - /// This should only be called from a function passed to `emit_option`. - fn emit_option_none(&mut self) -> Result<(), Self::Error>; - - /// Emit the `Some(x)` optional value. - /// - /// `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// This should only be called from a function passed to `emit_option`. - fn emit_option_some(&mut self, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit a sequence of values. - /// - /// This should be used for both array-like ordered sequences and set-like - /// unordered ones. - /// - /// * `len` is the number of values in the sequence. - /// * `f` is a function that will call `emit_seq_elt` for each value in the - /// sequence. - fn emit_seq(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit an element in a sequence. - /// - /// This should only be called from a function passed to `emit_seq`. - /// - /// * `idx` is the (zero-based) index of the value in the sequence. - /// * `f` is a function that will call the appropriate emit method to encode - /// the data object. - /// - /// Note that sequence elements must be emitted in order - starting with - /// index `0` and finishing with index `len-1`. - fn emit_seq_elt(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit an associative container (map). - /// - /// * `len` is the number of entries in the map. - /// * `f` is a function that will call `emit_map_elt_key` and - /// `emit_map_elt_val` for each entry in the map. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// - /// struct SimpleMap { - /// entries: Vec<(K,V)>, - /// } - /// - /// impl Encodable for SimpleMap { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// s.emit_map(self.entries.len(), |s| { - /// for (i, e) in self.entries.iter().enumerate() { - /// let (ref k, ref v) = *e; - /// try!(s.emit_map_elt_key(i, |s| k.encode(s))); - /// try!(s.emit_map_elt_val(i, |s| v.encode(s))); - /// } - /// Ok(()) - /// }) - /// } - /// } - /// ``` - fn emit_map(&mut self, len: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit the key for an entry in a map. - /// - /// This should only be called from a function passed to `emit_map`. - /// - /// * `idx` is the (zero-based) index of the entry in the map - /// * `f` is a function that will call the appropriate emit method to encode - /// the key. - /// - /// Note that map entries must be emitted in order - starting with index `0` - /// and finishing with index `len-1` - and for each entry, the key should be - /// emitted followed immediately by the value. - fn emit_map_elt_key(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; - - /// Emit the value for an entry in a map. - /// - /// This should only be called from a function passed to `emit_map`. - /// - /// * `idx` is the (zero-based) index of the entry in the map - /// * `f` is a function that will call the appropriate emit method to encode - /// the value. - /// - /// Note that map entries must be emitted in order - starting with index `0` - /// and finishing with index `len-1` - and for each entry, the key should be - /// emitted followed immediately by the value. - fn emit_map_elt_val(&mut self, idx: usize, f: F) -> Result<(), Self::Error> - where F: FnOnce(&mut Self) -> Result<(), Self::Error>; -} - -/// Trait for reading in an encoding for deserialization. -/// -/// This trait provides methods to decode basic types and generic forms of -/// collections. Implementations of `Decodable` use it to perform the actual -/// decoding of a type. -/// -/// Note that, as is typical with deserialization, the design of this API -/// assumes you know in advance the form of the data you are decoding (ie: what -/// type is encoded). -/// -/// Decoders can expect to only have a single "root" method call made on this -/// trait. Non-trivial types will call one of the collection-reading methods, -/// passing a function that may call other methods on the trait, but once the -/// collection-reading method has returned, decoding should be complete. -pub trait Decoder { - /// The error type for method results. - type Error; - - // Primitive types: - /// Read a nil value. - fn read_nil(&mut self) -> Result<(), Self::Error>; - - /// Read a usize value. - fn read_usize(&mut self) -> Result; - - /// Read a u64 value. - fn read_u64(&mut self) -> Result; - - /// Read a u32 value. - fn read_u32(&mut self) -> Result; - - /// Read a u16 value. - fn read_u16(&mut self) -> Result; - - /// Read a u8 value. - fn read_u8(&mut self) -> Result; - - /// Read a isize value. - fn read_isize(&mut self) -> Result; - - /// Read a i64 value. - fn read_i64(&mut self) -> Result; - - /// Read a i32 value. - fn read_i32(&mut self) -> Result; - - /// Read a i16 value. - fn read_i16(&mut self) -> Result; - - /// Read a i8 value. - fn read_i8(&mut self) -> Result; - - /// Read a bool value. - fn read_bool(&mut self) -> Result; - - /// Read a f64 value. - fn read_f64(&mut self) -> Result; - - /// Read a f32 value. - fn read_f32(&mut self) -> Result; - - /// Read a char value. - fn read_char(&mut self) -> Result; - - /// Read a string value. - fn read_str(&mut self) -> Result; - - // Compound types: - /// Read an enumeration value. - /// - /// * `name` indicates the enumeration type name. It may be used to - /// sanity-check the data being read. - /// * `f` is a function that will call `read_enum_variant` (or - /// `read_enum_struct_variant`) to read the actual value. - fn read_enum(&mut self, name: &str, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read an enumeration value. - /// - /// * `names` is a list of the enumeration variant names. - /// * `f` is a function that will call `read_enum_variant_arg` or - /// `read_enum_struct_variant_field` as appropriate to read the - /// associated values. It will be passed the index into `names` for the - /// variant that is encoded. - fn read_enum_variant(&mut self, names: &[&str], f: F) - -> Result - where F: FnMut(&mut Self, usize) -> Result; - - /// Read an unnamed data item for an enumeration variant. - /// - /// This should only be called from a function passed to `read_enum_variant` - /// or `read_enum_struct_variant`, and only when the index provided to that - /// function indicates that the variant has associated unnamed data. It - /// should be called once for each associated data item. - /// - /// * `a_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate read method to deocde - /// the data object. - /// - /// Note that variant data items must be read in order - starting with index - /// `0` and finishing with index `len-1`. Implementations may use `a_idx`, - /// the call order or both to select the correct data to decode. - fn read_enum_variant_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read an enumeration value. - /// - /// This is identical to `read_enum_variant`, and is only provided for - /// symmetry with the `Encoder` API. - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) - -> Result - where F: FnMut(&mut Self, usize) -> Result; - - /// Read a named data item for an enumeration variant. - /// - /// This should only be called from a function passed to `read_enum_variant` - /// or `read_enum_struct_variant`, and only when the index provided to that - /// function indicates that the variant has associated named data. It should - /// be called once for each associated field. - /// - /// * `f_name` is the name of the field. - /// * `f_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate read method to deocde - /// the data object. - /// - /// Note that fields must be read in order - starting with index `0` and - /// finishing with index `len-1`. Implementations may use `f_idx`, `f_name`, - /// the call order or any combination to choose the correct data to decode, - /// and may (but are not required to) return an error if these are - /// inconsistent. - fn read_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: usize, - f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read an struct value. - /// - /// * `s_name` indicates the struct type name. It may be used to - /// sanity-check the data being read. - /// * `len` indicates the number of fields in the struct. - /// * `f` is a function that will call `read_struct_field` for each field in - /// the struct. - fn read_struct(&mut self, s_name: &str, len: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read a field for a struct value. - /// - /// This should only be called from a function passed to `read_struct`. It - /// should be called once for each associated field. - /// - /// * `f_name` is the name of the field. - /// * `f_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate read method to deocde - /// the data object. - /// - /// Note that fields must be read in order - starting with index `0` and - /// finishing with index `len-1`. Implementations may use `f_idx`, `f_name`, - /// the call order or any combination to choose the correct data to decode, - /// and may (but are not required to) return an error if these are - /// inconsistent. - fn read_struct_field(&mut self, - f_name: &str, - f_idx: usize, - f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read a tuple value. - /// - /// * `len` is the number of items in the tuple. - /// * `f` is a function that will call `read_tuple_arg` for each item in the - /// tuple. - /// - /// Note that external `Decodable` implementations should not normally need - /// to use this method directly; it is meant for the use of this module's - /// own implementation of `Decodable` for tuples. - fn read_tuple(&mut self, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read a data item for a tuple. - /// - /// This should only be called from a function passed to `read_tuple`. - /// - /// * `a_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate read method to encode - /// the data object. - /// - /// Note that tuple items must be read in order - starting with index `0` - /// and finishing with index `len-1`. - fn read_tuple_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read a tuple struct value. - /// - /// * `s_name` is the name of the tuple struct. - /// * `len` is the number of items in the tuple struct. - /// * `f` is a function that calls `read_tuple_struct_arg` for each member. - fn read_tuple_struct(&mut self, s_name: &str, len: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read a data item for a tuple struct. - /// - /// This should only be called from a function passed to - /// `read_tuple_struct`. - /// - /// * `a_idx` is the (zero-based) index of the data item. - /// * `f` is a function that will call the appropriate read method to encode - /// the data object. - /// - /// Note that tuple struct items must be read in order - starting with index - /// `0` and finishing with index `len-1`. - fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - // Specialized types: - /// Read an optional value. - /// - /// `f` is a function that will will be passed be passed `false` if the - /// value is unset, and `true` if it is set. If the function is passed - /// `true`, it will call the appropriate read methods to read the associated - /// data type. - /// - /// This method allows decoders to handle `Option` values specially, - /// rather than using the generic enum methods, because many encoding - /// formats have a built-in "optional" concept. - /// - /// Note that external `Decodable` implementations should not normally need - /// to use this method directly; it is meant for the use of this module's - /// own implementation of `Decodable` for `Option`. - fn read_option(&mut self, f: F) -> Result - where F: FnMut(&mut Self, bool) -> Result; - - /// Read a sequence of values. - /// - /// This should be used for both array-like ordered sequences and set-like - /// unordered ones. - /// - /// * `f` is a function that will be passed the length of the sequence, and - /// will call `read_seq_elt` for each value in the sequence. - fn read_seq(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result; - - /// Read an element in the sequence. - /// - /// This should only be called from a function passed to `read_seq`. - /// - /// * `idx` is the (zero-based) index of the value in the sequence. - /// * `f` is a function that will call the appropriate read method to decode - /// the data object. - /// - /// Note that sequence elements must be read in order - starting with index - /// `0` and finishing with index `len-1`. - fn read_seq_elt(&mut self, idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read an associative container (map). - /// - /// * `f` is a function that will be passed the number of entries in the - /// map, and will call `read_map_elt_key` and `read_map_elt_val` to decode - /// each entry. - fn read_map(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result; - - /// Read the key for an entry in a map. - /// - /// This should only be called from a function passed to `read_map`. - /// - /// * `idx` is the (zero-based) index of the entry in the map - /// * `f` is a function that will call the appropriate read method to decode - /// the key. - /// - /// Note that map entries must be read in order - starting with index `0` - /// and finishing with index `len-1` - and for each entry, the key should be - /// read followed immediately by the value. - fn read_map_elt_key(&mut self, idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - /// Read the value for an entry in a map. - /// - /// This should only be called from a function passed to `read_map`. - /// - /// * `idx` is the (zero-based) index of the entry in the map - /// * `f` is a function that will call the appropriate read method to decode - /// the value. - /// - /// Note that map entries must be read in order - starting with index `0` - /// and finishing with index `len-1` - and for each entry, the key should be - /// read followed immediately by the value. - fn read_map_elt_val(&mut self, idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result; - - // Failure - /// Record a decoding error. - /// - /// This allows `Decodable` implementations to report an error using a - /// `Decoder` implementation's error type when inconsistent data is read. - /// For example, when reading a fixed-length array and the wrong length is - /// given by `read_seq`. - fn error(&mut self, err: &str) -> Self::Error; -} - -/// Trait for serializing a type. -/// -/// This can be implemented for custom data types to allow them to be encoded -/// with `Encoder` implementations. Most of Rust's built-in or standard data -/// types (like `i32` and `Vec`) have `Encodable` implementations provided by -/// this module. -/// -/// Note that, in general, you should let the compiler implement this for you by -/// using the `derive(RustcEncodable)` attribute. -/// -/// # Examples -/// -/// ```rust -/// extern crate rustc_serialize; -/// -/// #[derive(RustcEncodable)] -/// struct Point { -/// x: i32, -/// y: i32, -/// } -/// # fn main() {} -/// ``` -/// -/// This generates code equivalent to: -/// -/// ```rust -/// extern crate rustc_serialize; -/// use rustc_serialize::Encodable; -/// use rustc_serialize::Encoder; -/// -/// struct Point { -/// x: i32, -/// y: i32, -/// } -/// -/// impl Encodable for Point { -/// fn encode(&self, s: &mut S) -> Result<(), S::Error> { -/// s.emit_struct("Point", 2, |s| { -/// try!(s.emit_struct_field("x", 0, |s| { -/// s.emit_i32(self.x) -/// })); -/// try!(s.emit_struct_field("y", 1, |s| { -/// s.emit_i32(self.y) -/// })); -/// Ok(()) -/// }) -/// } -/// } -/// # fn main() {} -/// ``` -pub trait Encodable { - /// Serialize a value using an `Encoder`. - fn encode(&self, s: &mut S) -> Result<(), S::Error>; -} - -/// Trait for deserializing a type. -/// -/// This can be implemented for custom data types to allow them to be decoded -/// with `Decoder` implementations. Most of Rust's built-in or standard data -/// types (like `i32` and `Vec`) have `Decodable` implementations provided by -/// this module. -/// -/// Note that, in general, you should let the compiler implement this for you by -/// using the `derive(RustcDecodable)` attribute. -/// -/// # Examples -/// -/// ```rust -/// extern crate rustc_serialize; -/// -/// #[derive(RustcDecodable)] -/// struct Point { -/// x: i32, -/// y: i32, -/// } -/// # fn main() {} -/// ``` -/// -/// This generates code equivalent to: -/// -/// ```rust -/// extern crate rustc_serialize; -/// use rustc_serialize::Decodable; -/// use rustc_serialize::Decoder; -/// -/// struct Point { -/// x: i32, -/// y: i32, -/// } -/// -/// impl Decodable for Point { -/// fn decode(d: &mut D) -> Result { -/// d.read_struct("Point", 2, |d| { -/// let x = try!(d.read_struct_field("x", 0, |d| { d.read_i32() })); -/// let y = try!(d.read_struct_field("y", 1, |d| { d.read_i32() })); -/// Ok(Point{ x: x, y: y }) -/// }) -/// } -/// } -/// # fn main() {} -/// ``` -pub trait Decodable: Sized { - /// Deserialize a value using a `Decoder`. - fn decode(d: &mut D) -> Result; -} - -impl Encodable for usize { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_usize(*self) - } -} - -impl Decodable for usize { - fn decode(d: &mut D) -> Result { - d.read_usize() - } -} - -impl Encodable for u8 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_u8(*self) - } -} - -impl Decodable for u8 { - fn decode(d: &mut D) -> Result { - d.read_u8() - } -} - -impl Encodable for u16 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_u16(*self) - } -} - -impl Decodable for u16 { - fn decode(d: &mut D) -> Result { - d.read_u16() - } -} - -impl Encodable for u32 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_u32(*self) - } -} - -impl Decodable for u32 { - fn decode(d: &mut D) -> Result { - d.read_u32() - } -} - -impl Encodable for u64 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_u64(*self) - } -} - -impl Decodable for u64 { - fn decode(d: &mut D) -> Result { - d.read_u64() - } -} - -impl Encodable for isize { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_isize(*self) - } -} - -impl Decodable for isize { - fn decode(d: &mut D) -> Result { - d.read_isize() - } -} - -impl Encodable for i8 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_i8(*self) - } -} - -impl Decodable for i8 { - fn decode(d: &mut D) -> Result { - d.read_i8() - } -} - -impl Encodable for i16 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_i16(*self) - } -} - -impl Decodable for i16 { - fn decode(d: &mut D) -> Result { - d.read_i16() - } -} - -impl Encodable for i32 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_i32(*self) - } -} - -impl Decodable for i32 { - fn decode(d: &mut D) -> Result { - d.read_i32() - } -} - -impl Encodable for i64 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_i64(*self) - } -} - -impl Decodable for i64 { - fn decode(d: &mut D) -> Result { - d.read_i64() - } -} - -impl Encodable for str { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(self) - } -} - -impl Encodable for String { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_str(self) - } -} - -impl Decodable for String { - fn decode(d: &mut D) -> Result { - d.read_str() - } -} - -impl Encodable for f32 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_f32(*self) - } -} - -impl Decodable for f32 { - fn decode(d: &mut D) -> Result { - d.read_f32() - } -} - -impl Encodable for f64 { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_f64(*self) - } -} - -impl Decodable for f64 { - fn decode(d: &mut D) -> Result { - d.read_f64() - } -} - -impl Encodable for bool { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_bool(*self) - } -} - -impl Decodable for bool { - fn decode(d: &mut D) -> Result { - d.read_bool() - } -} - -impl Encodable for char { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_char(*self) - } -} - -impl Decodable for char { - fn decode(d: &mut D) -> Result { - d.read_char() - } -} - -impl Encodable for () { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_nil() - } -} - -impl Decodable for () { - fn decode(d: &mut D) -> Result<(), D::Error> { - d.read_nil() - } -} - -impl<'a, T: ?Sized + Encodable> Encodable for &'a T { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl Encodable for Box { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl< T: Decodable> Decodable for Box { - fn decode(d: &mut D) -> Result, D::Error> { - Ok(Box::new(try!(Decodable::decode(d)))) - } -} - -impl< T: Decodable> Decodable for Box<[T]> { - fn decode(d: &mut D) -> Result, D::Error> { - let v: Vec = try!(Decodable::decode(d)); - Ok(v.into_boxed_slice()) - } -} - -impl Encodable for Rc { - #[inline] - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl Decodable for Rc { - #[inline] - fn decode(d: &mut D) -> Result, D::Error> { - Ok(Rc::new(try!(Decodable::decode(d)))) - } -} - -impl<'a, T:Encodable + ToOwned + ?Sized> Encodable for Cow<'a, T> { - #[inline] - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl<'a, T: ?Sized> Decodable for Cow<'a, T> - where T: ToOwned, T::Owned: Decodable -{ - #[inline] - fn decode(d: &mut D) -> Result, D::Error> { - Ok(Cow::Owned(try!(Decodable::decode(d)))) - } -} - -impl Encodable for [T] { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - try!(s.emit_seq_elt(i, |s| e.encode(s))) - } - Ok(()) - }) - } -} - -impl Encodable for Vec { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq(self.len(), |s| { - for (i, e) in self.iter().enumerate() { - try!(s.emit_seq_elt(i, |s| e.encode(s))) - } - Ok(()) - }) - } -} - -impl Decodable for Vec { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_seq(|d, len| { - let mut v = Vec::with_capacity(cap_capacity::(len)); - for i in 0..len { - v.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); - } - Ok(v) - }) - } -} - -impl Encodable for Option { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_option(|s| { - match *self { - None => s.emit_option_none(), - Some(ref v) => s.emit_option_some(|s| v.encode(s)), - } - }) - } -} - -impl Decodable for Option { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_option(|d, b| { - if b { - Ok(Some(try!(Decodable::decode(d)))) - } else { - Ok(None) - } - }) - } -} - -impl Encodable for Result { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_enum("Result", |s| { - match *self { - Ok(ref v) => { - s.emit_enum_variant("Ok", 0, 1, |s| { - try!(s.emit_enum_variant_arg(0, |s| { - v.encode(s) - })); - Ok(()) - }) - } - Err(ref v) => { - s.emit_enum_variant("Err", 1, 1, |s| { - try!(s.emit_enum_variant_arg(0, |s| { - v.encode(s) - })); - Ok(()) - }) - } - } - }) - } -} - -impl Decodable for Result { - fn decode(d: &mut D) -> Result, D::Error> { - d.read_enum("Result", |d| { - d.read_enum_variant(&["Ok", "Err"], |d, idx| { - match idx { - 0 => { - d.read_enum_variant_arg(0, |d| { - T::decode(d) - }).map(|v| Ok(v)) - } - 1 => { - d.read_enum_variant_arg(0, |d| { - E::decode(d) - }).map(|v| Err(v)) - } - _ => panic!("Internal error"), - } - }) - }) - } -} - -impl Encodable for PhantomData { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_nil() - } -} - -impl Decodable for PhantomData { - fn decode(_d: &mut D) -> Result, D::Error> { - Ok(PhantomData) - } -} - -macro_rules! peel { - ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) -} - -/// Evaluates to the number of identifiers passed to it, for example: -/// `count_idents!(a, b, c) == 3 -macro_rules! count_idents { - () => { 0 }; - ($_i:ident, $($rest:ident,)*) => { 1 + count_idents!($($rest,)*) } -} - -macro_rules! tuple { - () => (); - ( $($name:ident,)+ ) => ( - impl<$($name:Decodable),*> Decodable for ($($name,)*) { - fn decode(d: &mut D) -> Result<($($name,)*), D::Error> { - let len: usize = count_idents!($($name,)*); - d.read_tuple(len, |d| { - let mut i = 0; - let ret = ($(try!(d.read_tuple_arg({ i+=1; i-1 }, - |d| -> Result<$name,D::Error> { - Decodable::decode(d) - })),)*); - return Ok(ret); - }) - } - } - impl<$($name:Encodable),*> Encodable for ($($name,)*) { - #[allow(non_snake_case)] - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - let ($(ref $name,)*) = *self; - let mut n = 0; - $(let $name = $name; n += 1;)* - s.emit_tuple(n, |s| { - let mut i = 0; - $(try!(s.emit_tuple_arg({ i+=1; i-1 }, |s| $name.encode(s)));)* - Ok(()) - }) - } - } - peel! { $($name,)* } - ) -} - -tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } - -macro_rules! array { - () => (); - ($len:expr, $($idx:expr,)*) => { - impl Decodable for [T; $len] { - fn decode(d: &mut D) -> Result<[T; $len], D::Error> { - d.read_seq(|d, len| { - if len != $len { - return Err(d.error("wrong array length")); - } - Ok([$( - try!(d.read_seq_elt($len - $idx - 1, - |d| Decodable::decode(d))) - ),*]) - }) - } - } - - impl Encodable for [T; $len] { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - s.emit_seq($len, |s| { - for i in 0..$len { - try!(s.emit_seq_elt(i, |s| self[i].encode(s))); - } - Ok(()) - }) - } - } - array! { $($idx,)* } - } -} - -array! { - 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -} - -impl Encodable for path::Path { - #[cfg(target_os = "redox")] - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - self.as_os_str().to_str().unwrap().encode(e) - } - #[cfg(unix)] - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - use std::os::unix::prelude::*; - self.as_os_str().as_bytes().encode(e) - } - #[cfg(windows)] - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - use std::os::windows::prelude::*; - let v = self.as_os_str().encode_wide().collect::>(); - v.encode(e) - } -} - -impl Encodable for path::PathBuf { - fn encode(&self, e: &mut S) -> Result<(), S::Error> { - (**self).encode(e) - } -} - -impl Decodable for path::PathBuf { - #[cfg(target_os = "redox")] - fn decode(d: &mut D) -> Result { - let string: String = try!(Decodable::decode(d)); - let s: OsString = OsString::from(string); - let mut p = path::PathBuf::new(); - p.push(s); - Ok(p) - } - #[cfg(unix)] - fn decode(d: &mut D) -> Result { - use std::os::unix::prelude::*; - let bytes: Vec = try!(Decodable::decode(d)); - let s: OsString = OsStringExt::from_vec(bytes); - let mut p = path::PathBuf::new(); - p.push(s); - Ok(p) - } - #[cfg(windows)] - fn decode(d: &mut D) -> Result { - use std::os::windows::prelude::*; - let bytes: Vec = try!(Decodable::decode(d)); - let s: OsString = OsStringExt::from_wide(&bytes); - let mut p = path::PathBuf::new(); - p.push(s); - Ok(p) - } -} - -impl Encodable for Cell { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.get().encode(s) - } -} - -impl Decodable for Cell { - fn decode(d: &mut D) -> Result, D::Error> { - Ok(Cell::new(try!(Decodable::decode(d)))) - } -} - -// FIXME: #15036 -// Should use `try_borrow`, returning a -// `encoder.error("attempting to Encode borrowed RefCell")` -// from `encode` when `try_borrow` returns `None`. - -impl Encodable for RefCell { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.borrow().encode(s) - } -} - -impl Decodable for RefCell { - fn decode(d: &mut D) -> Result, D::Error> { - Ok(RefCell::new(try!(Decodable::decode(d)))) - } -} - -impl Encodable for Arc { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - (**self).encode(s) - } -} - -impl Decodable for Arc { - fn decode(d: &mut D) -> Result, D::Error> { - Ok(Arc::new(try!(Decodable::decode(d)))) - } -} - -// ___________________________________________________________________________ -// Helper routines - -/// Trait with helper functions for implementing `Encodable`. -/// -/// This trait is implemented for everything that implements `Encoder`. -/// `Encodable` implementations can make use of it to make their implementations -/// easier. -pub trait EncoderHelpers: Encoder { - /// Emit a vector as a sequence. - /// - /// Storing sequences as vectors is a common pattern. This method makes - /// encoding such sequences easier by wrapping the calls to - /// `Encoder::emit_seq` and `Encoder::emit_seq_elt`. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Encodable; - /// use rustc_serialize::Encoder; - /// use rustc_serialize::EncoderHelpers; - /// - /// struct NumberSequence { - /// elements: Vec, - /// } - /// - /// impl Encodable for NumberSequence { - /// fn encode(&self, s: &mut S) -> Result<(), S::Error> { - /// s.emit_struct("NumberSequence", 1, |s| { - /// s.emit_struct_field("elements", 0, |s| { - /// s.emit_from_vec(&self.elements, |s,e| { - /// s.emit_i32(*e) - /// }) - /// }) - /// }) - /// } - /// } - /// ``` - fn emit_from_vec(&mut self, v: &[T], f: F) - -> Result<(), ::Error> - where F: FnMut(&mut Self, &T) -> Result<(), ::Error>; -} - -impl EncoderHelpers for S { - fn emit_from_vec(&mut self, v: &[T], mut f: F) -> Result<(), S::Error> where - F: FnMut(&mut S, &T) -> Result<(), S::Error>, - { - self.emit_seq(v.len(), |this| { - for (i, e) in v.iter().enumerate() { - try!(this.emit_seq_elt(i, |this| { - f(this, e) - })); - } - Ok(()) - }) - } -} - -/// Trait with helper functions for implementing `Decodable`. -/// -/// This trait is implemented for everything that implements `Decoder`. -/// `Decodable` implementations can make use of it to make their implementations -/// easier. -pub trait DecoderHelpers: Decoder { - /// Read a sequence into a vector. - /// - /// Storing sequences as vectors is a common pattern. This method makes - /// deserializing such sequences easier by wrapping the calls to - /// `Decoder::read_seq` and `Decoder::read_seq_elt`. - /// - /// # Examples - /// - /// ``` - /// use rustc_serialize::Decodable; - /// use rustc_serialize::Decoder; - /// use rustc_serialize::DecoderHelpers; - /// - /// struct NumberSequence { - /// elements: Vec, - /// } - /// - /// impl Decodable for NumberSequence { - /// fn decode(d: &mut D) -> Result { - /// d.read_struct("NumberSequence", 2, |d| { - /// Ok(NumberSequence{ - /// elements: try!(d.read_struct_field("elements", 0, |d| { - /// d.read_to_vec(|d| { d.read_i32() }) - /// })) - /// }) - /// }) - /// } - /// } - /// ``` - fn read_to_vec(&mut self, f: F) - -> Result, ::Error> where - F: FnMut(&mut Self) -> Result::Error>; -} - -impl DecoderHelpers for D { - fn read_to_vec(&mut self, mut f: F) -> Result, D::Error> where F: - FnMut(&mut D) -> Result, - { - self.read_seq(|this, len| { - let mut v = Vec::with_capacity(cap_capacity::(len)); - for i in 0..len { - v.push(try!(this.read_seq_elt(i, |this| f(this)))); - } - Ok(v) - }) - } -} - -#[test] -#[allow(unused_variables)] -fn capacity_rules() { - use std::usize::MAX; - use std::collections::{HashMap, HashSet}; - - struct MyDecoder; - impl Decoder for MyDecoder { - type Error = (); - - // Primitive types: - fn read_nil(&mut self) -> Result<(), Self::Error> { Err(()) } - fn read_usize(&mut self) -> Result { Err(()) } - fn read_u64(&mut self) -> Result { Err(()) } - fn read_u32(&mut self) -> Result { Err(()) } - fn read_u16(&mut self) -> Result { Err(()) } - fn read_u8(&mut self) -> Result { Err(()) } - fn read_isize(&mut self) -> Result { Err(()) } - fn read_i64(&mut self) -> Result { Err(()) } - fn read_i32(&mut self) -> Result { Err(()) } - fn read_i16(&mut self) -> Result { Err(()) } - fn read_i8(&mut self) -> Result { Err(()) } - fn read_bool(&mut self) -> Result { Err(()) } - fn read_f64(&mut self) -> Result { Err(()) } - fn read_f32(&mut self) -> Result { Err(()) } - fn read_char(&mut self) -> Result { Err(()) } - fn read_str(&mut self) -> Result { Err(()) } - - // Compound types: - fn read_enum(&mut self, name: &str, f: F) -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_enum_variant(&mut self, names: &[&str], f: F) - -> Result - where F: FnMut(&mut Self, usize) -> Result { Err(()) } - fn read_enum_variant_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_enum_struct_variant(&mut self, names: &[&str], f: F) - -> Result - where F: FnMut(&mut Self, usize) -> Result { Err(()) } - fn read_enum_struct_variant_field(&mut self, - f_name: &str, - f_idx: usize, - f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_struct(&mut self, s_name: &str, len: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - fn read_struct_field(&mut self, - f_name: &str, - f_idx: usize, - f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_tuple(&mut self, len: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - fn read_tuple_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_tuple_struct(&mut self, s_name: &str, len: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - fn read_tuple_struct_arg(&mut self, a_idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - // Specialized types: - fn read_option(&mut self, f: F) -> Result - where F: FnMut(&mut Self, bool) -> Result { Err(()) } - - fn read_seq(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result { - f(self, MAX) - } - fn read_seq_elt(&mut self, idx: usize, f: F) -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - fn read_map(&mut self, f: F) -> Result - where F: FnOnce(&mut Self, usize) -> Result { - f(self, MAX) - } - fn read_map_elt_key(&mut self, idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - fn read_map_elt_val(&mut self, idx: usize, f: F) - -> Result - where F: FnOnce(&mut Self) -> Result { Err(()) } - - // Failure - fn error(&mut self, err: &str) -> Self::Error { () } - } - - let mut dummy = MyDecoder; - let vec_result: Result, ()> = Decodable::decode(&mut dummy); - assert!(vec_result.is_err()); - - let map_result: Result, ()> = Decodable::decode(&mut dummy); - assert!(map_result.is_err()); - - let set_result: Result, ()> = Decodable::decode(&mut dummy); - assert!(set_result.is_err()); -} diff --git a/third_party/rust/ryu/.cargo-checksum.json b/third_party/rust/ryu/.cargo-checksum.json new file mode 100644 index 000000000000..5ec8b0e9d264 --- /dev/null +++ b/third_party/rust/ryu/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{".travis.yml":"f73b83dfd8c84e2af27d780e93441a071507c8c2d981a73844558fe72717448e","Cargo.toml":"a97493cb1e3f170d30a5f8d92ae65185103083baf408eb5c0bd8f64a7ffdf007","LICENSE-APACHE":"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4","README.md":"d150ab564033cacab1e6e806b13e78bb241818e950ffa4bf2623e6bd3bc64fb3","benchmark/benchmark.rs":"5ee2d5f68f6fa93f24e3828c9e8e269c22ce3ea96c0804def61b0b3026ad021f","build.rs":"96e9308d3a7a23a4c222892be8f29f45b13bffaed751f2e5b0b247230b65f360","src/buffer/mod.rs":"bcdc3db1c97b36c04c4445c4a7fba768be7a8b16e0f8bc7bab86ac06256a9750","src/common.rs":"f165881b718867b7801044bd29fa7f4322ebfc63d45d462d4a703253f8812a3e","src/d2s.rs":"35e0982e83d8c46f4304148d0454957b62be5f17480ad417d893521d578ad86e","src/d2s_full_table.rs":"7f7e475c54ae69d834574603bde9dcbe9f0d7cb09cfc3cda025319c903996bf8","src/d2s_small_table.rs":"f1bc5b328be636f100315ba818545e7d3c125cacec8487ed12f59f50d70b945e","src/digit_table.rs":"02351ca54cb8cb3679f635115dd094f32fd91750e9f66103c1ee9ec3db507072","src/f2s.rs":"2a59cc3ea57244ef4e926d98284a33363fb67452e20f24141395312173698e32","src/lib.rs":"268d75e445101f1edc0ced93852941ab9b150f1faea642490a03e8a613a33589","src/mulshift128.rs":"b539411c08b7cde489b876addc346a061e3594ed707fe577a3cdff6d26b0e1f8","src/pretty/exponent.rs":"15fd163fdb81573d331f24fda37f5403931512ffb08715a2695f0a0256b69b84","src/pretty/mantissa.rs":"7b0ea97069ee597f3bc0c8f2f3354c75be93d01c6a8135104ae82cd83df318e0","src/pretty/mod.rs":"f691267e66ce6f13d6db17ca6b93065e50a669e73916cbd22c8bfb3e33ad85fe","tests/d2s_table_test.rs":"57b541dc08c54c83979f18a20f8895daac3ad32628b140c66b09f42bce7f2691","tests/d2s_test.rs":"9abea253a30d96815688a34f20e2b3eff40c9d8b9a1209d7e927ba5a63efd74a","tests/exhaustive.rs":"0e01491936cb6b5ae68d92e50b6f7cebb26362774e860df103695ecc1f71fa7b","tests/f2s_test.rs":"7fa9dd515ed42947f570243a6d0656b6e2861c1399f679d96317dc109018d59b","tests/macros/mod.rs":"45eed20e9a3d8d9b673f504e8194f762223346adec46a6fbf1e0717eaeee85bc"},"package":"fd0568787116e13c652377b6846f5931454a363a8fdf8ae50463ee40935b278b"} \ No newline at end of file diff --git a/third_party/rust/ryu/.travis.yml b/third_party/rust/ryu/.travis.yml new file mode 100644 index 000000000000..9039ef6101da --- /dev/null +++ b/third_party/rust/ryu/.travis.yml @@ -0,0 +1,13 @@ +language: rust + +rust: + - nightly + - beta + - stable + +matrix: + include: + - rust: 1.15.0 + script: + - cargo build + - cargo build --features small diff --git a/third_party/rust/ryu/Cargo.toml b/third_party/rust/ryu/Cargo.toml new file mode 100644 index 000000000000..0b4d70c9de2e --- /dev/null +++ b/third_party/rust/ryu/Cargo.toml @@ -0,0 +1,39 @@ +# 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 believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "ryu" +version = "0.2.4" +authors = ["David Tolnay "] +build = "build.rs" +description = "Fast floating point to string conversion" +documentation = "https://docs.rs/ryu" +readme = "README.md" +license = "Apache-2.0" +repository = "https://github.com/dtolnay/ryu" + +[[example]] +name = "benchmark" +path = "benchmark/benchmark.rs" +[dependencies.no-panic] +version = "0.1" +optional = true +[dev-dependencies.num_cpus] +version = "1.8" + +[dev-dependencies.rand] +version = "0.5" + +[features] +small = [] +[badges.travis-ci] +repository = "dtolnay/ryu" diff --git a/third_party/rust/ryu/LICENSE-APACHE b/third_party/rust/ryu/LICENSE-APACHE new file mode 100644 index 000000000000..261eeb9e9f8b --- /dev/null +++ b/third_party/rust/ryu/LICENSE-APACHE @@ -0,0 +1,201 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/rust/ryu/README.md b/third_party/rust/ryu/README.md new file mode 100644 index 000000000000..ee7234604506 --- /dev/null +++ b/third_party/rust/ryu/README.md @@ -0,0 +1,74 @@ +# Ryū + +[![Build Status](https://api.travis-ci.org/dtolnay/ryu.svg?branch=master)](https://travis-ci.org/dtolnay/ryu) +[![Latest Version](https://img.shields.io/crates/v/ryu.svg)](https://crates.io/crates/ryu) +[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/ryu) +[![Rustc Version 1.15+](https://img.shields.io/badge/rustc-1.15+-lightgray.svg)](https://blog.rust-lang.org/2017/02/02/Rust-1.15.html) + +Pure Rust implementation of Ryū, an algorithm to quickly convert floating point +numbers to decimal strings. + +The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf Adams +includes a complete correctness proof of the algorithm. The paper is available +under the creative commons CC-BY-SA license. + +This Rust implementation is a line-by-line port of Ulf Adams' implementation in +C, [https://github.com/ulfjack/ryu][upstream]. The `ryu::raw` module exposes +exactly the API and formatting of the C implementation as unsafe pure Rust +functions. There is additionally a safe API as demonstrated in the example code +below. The safe API uses the same underlying Ryū algorithm but diverges from the +formatting of the C implementation to produce more human-readable output, for +example `0.3` rather than `3E-1`. + +*Requirements: this crate supports any compiler version back to rustc 1.15; it +uses nothing from the Rust standard library so is usable from no_std crates.* + +[paper]: https://dl.acm.org/citation.cfm?id=3192369 +[upstream]: https://github.com/ulfjack/ryu/tree/4ffc2b759e4b0a431b35dbfbfd6e0e85fdd15a69 + +```toml +[dependencies] +ryu = "0.2" +``` + +## Examples + +```rust +extern crate ryu; + +fn main() { + let mut buffer = ryu::Buffer::new(); + let printed = buffer.format(1.234); + assert_eq!(printed, "1.234"); +} +``` + +## Performance + +You can run upstream's benchmarks with: + +```console +$ git clone https://github.com/ulfjack/ryu c-ryu +$ cd c-ryu +$ bazel run -c opt //ryu/benchmark +``` + +And our benchmarks with: + +```console +$ git clone https://github.com/ulfjack/ryu rust-ryu +$ cd rust-ryu +$ cargo run --example benchmark --release +``` + +These benchmarks measure the average time to print a 32-bit float and average +time to print a 64-bit float, where the inputs are distributed as uniform random +bit patterns 32 and 64 bits wide. + +The upstream C code, the unsafe direct Rust port, and the safe pretty Rust API +all perform the same, taking around 21 nanoseconds to format a 32-bit float and +31 nanoseconds to format a 64-bit float. + +## License + +Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) diff --git a/third_party/rust/ryu/benchmark/benchmark.rs b/third_party/rust/ryu/benchmark/benchmark.rs new file mode 100644 index 000000000000..f42cf237ba5a --- /dev/null +++ b/third_party/rust/ryu/benchmark/benchmark.rs @@ -0,0 +1,86 @@ +extern crate rand; +extern crate ryu; + +use rand::{Rng, SeedableRng}; + +const SAMPLES: usize = 10000; +const ITERATIONS: usize = 1000; + +struct MeanAndVariance { + n: i64, + mean: f64, + m2: f64, +} + +impl MeanAndVariance { + fn new() -> Self { + MeanAndVariance { + n: 0, + mean: 0.0, + m2: 0.0, + } + } + + fn update(&mut self, x: f64) { + self.n += 1; + let d = x - self.mean; + self.mean += d / self.n as f64; + let d2 = x - self.mean; + self.m2 += d * d2; + } + + fn variance(&self) -> f64 { + self.m2 / (self.n - 1) as f64 + } + + fn stddev(&self) -> f64 { + self.variance().sqrt() + } +} + +macro_rules! benchmark { + ($name:ident, $ty:ident) => { + fn $name() -> usize { + let mut rng = rand::prng::XorShiftRng::from_seed([123u8; 16]); + let mut mv = MeanAndVariance::new(); + let mut throwaway = 0; + for _ in 0..SAMPLES { + let f = loop { + let f = $ty::from_bits(rng.gen()); + if f.is_finite() { + break f; + } + }; + + let t1 = std::time::SystemTime::now(); + for _ in 0..ITERATIONS { + throwaway += ryu::Buffer::new().format(f).len(); + } + let duration = t1.elapsed().unwrap(); + let nanos = duration.as_secs() * 1_000_000_000 + duration.subsec_nanos() as u64; + mv.update(nanos as f64 / ITERATIONS as f64); + } + println!( + "{:12} {:8.3} {:8.3}", + concat!(stringify!($name), ":"), + mv.mean, + mv.stddev(), + ); + throwaway + } + }; +} + +benchmark!(pretty32, f32); +benchmark!(pretty64, f64); + +fn main() { + println!("{:>20}{:>9}", "Average", "Stddev"); + let mut throwaway = 0; + throwaway += pretty32(); + throwaway += pretty64(); + if std::env::var_os("ryu-benchmark").is_some() { + // Prevent the compiler from optimizing the code away. + println!("{}", throwaway); + } +} diff --git a/third_party/rust/ryu/build.rs b/third_party/rust/ryu/build.rs new file mode 100644 index 000000000000..4f721827447d --- /dev/null +++ b/third_party/rust/ryu/build.rs @@ -0,0 +1,54 @@ +use std::env; +use std::process::Command; +use std::str::{self, FromStr}; + +// The rustc-cfg strings below are *not* public API. Please let us know by +// opening a GitHub issue if your build environment requires some way to enable +// these cfgs other than by executing our build script. +fn main() { + let minor = match rustc_minor_version() { + Some(minor) => minor, + None => return, + }; + + // 128-bit integers stabilized in Rust 1.26: + // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html + if minor >= 26 { + println!("cargo:rustc-cfg=integer128"); + } + + // #[must_use] on functions stabilized in Rust 1.27: + // https://blog.rust-lang.org/2018/06/21/Rust-1.27.html + if minor >= 27 { + println!("cargo:rustc-cfg=must_use_return"); + } +} + +fn rustc_minor_version() -> Option { + let rustc = match env::var_os("RUSTC") { + Some(rustc) => rustc, + None => return None, + }; + + let output = match Command::new(rustc).arg("--version").output() { + Ok(output) => output, + Err(_) => return None, + }; + + let version = match str::from_utf8(&output.stdout) { + Ok(version) => version, + Err(_) => return None, + }; + + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + + let next = match pieces.next() { + Some(next) => next, + None => return None, + }; + + u32::from_str(next).ok() +} diff --git a/third_party/rust/ryu/src/buffer/mod.rs b/third_party/rust/ryu/src/buffer/mod.rs new file mode 100644 index 000000000000..069074ce1aff --- /dev/null +++ b/third_party/rust/ryu/src/buffer/mod.rs @@ -0,0 +1,97 @@ +use core::{mem, slice, str}; + +use pretty; + +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +/// Safe API for formatting floating point numbers to text. +/// +/// ## Example +/// +/// ```rust +/// let mut buffer = ryu::Buffer::new(); +/// let printed = buffer.format(1.234); +/// assert_eq!(printed, "1.234"); +/// ``` +#[derive(Copy, Clone)] +pub struct Buffer { + bytes: [u8; 24], +} + +impl Buffer { + /// This is a cheap operation; you don't need to worry about reusing buffers + /// for efficiency. + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn new() -> Self { + Buffer { + bytes: unsafe { mem::uninitialized() }, + } + } + + /// Print a floating point number into this buffer and return a reference to + /// its string representation within the buffer. + /// + /// # Special cases + /// + /// This function **does not** check for NaN or infinity. If the input + /// number is not a finite float, the printed representation will be some + /// correctly formatted but unspecified numerical value. + /// + /// Please check [`is_finite`] yourself before calling this function, or + /// check [`is_nan`] and [`is_infinite`] and handle those cases yourself. + /// + /// [`is_finite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_finite + /// [`is_nan`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_nan + /// [`is_infinite`]: https://doc.rust-lang.org/std/primitive.f64.html#method.is_infinite + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + pub fn format(&mut self, f: F) -> &str { + unsafe { + let n = f.write_to_ryu_buffer(&mut self.bytes[0]); + debug_assert!(n <= self.bytes.len()); + let slice = slice::from_raw_parts(&self.bytes[0], n); + str::from_utf8_unchecked(slice) + } + } +} + +impl Default for Buffer { + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + fn default() -> Self { + Buffer::new() + } +} + +/// A floating point number, f32 or f64, that can be written into a +/// [`ryu::Buffer`][Buffer]. +/// +/// This trait is sealed and cannot be implemented for types outside of the +/// `ryu` crate. +pub trait Float: Sealed { + // Not public API. + #[doc(hidden)] + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize; +} + +impl Float for f32 { + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize { + pretty::f2s_buffered_n(self, result) + } +} + +impl Float for f64 { + #[inline] + #[cfg_attr(feature = "no-panic", no_panic)] + unsafe fn write_to_ryu_buffer(self, result: *mut u8) -> usize { + pretty::d2s_buffered_n(self, result) + } +} + +pub trait Sealed {} +impl Sealed for f32 {} +impl Sealed for f64 {} diff --git a/third_party/rust/ryu/src/common.rs b/third_party/rust/ryu/src/common.rs new file mode 100644 index 000000000000..638370cf73e6 --- /dev/null +++ b/third_party/rust/ryu/src/common.rs @@ -0,0 +1,72 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use core::ptr; + +// Returns e == 0 ? 1 : ceil(log_2(5^e)). +#[cfg_attr(feature = "no-panic", inline)] +pub fn pow5bits(e: i32) -> u32 { + // This approximation works up to the point that the multiplication overflows at e = 3529. + // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater + // than 2^9297. + debug_assert!(e >= 0); + debug_assert!(e <= 3528); + ((e as u32 * 1217359) >> 19) + 1 +} + +// Returns floor(log_10(2^e)). +#[cfg_attr(feature = "no-panic", inline)] +pub fn log10_pow2(e: i32) -> i32 { + // The first value this approximation fails for is 2^1651 which is just greater than 10^297. + debug_assert!(e >= 0); + debug_assert!(e <= 1650); + ((e as u32 * 78913) >> 18) as i32 +} + +// Returns floor(log_10(5^e)). +#[cfg_attr(feature = "no-panic", inline)] +pub fn log10_pow5(e: i32) -> i32 { + // The first value this approximation fails for is 5^2621 which is just greater than 10^1832. + debug_assert!(e >= 0); + debug_assert!(e <= 2620); + ((e as u32 * 732923) >> 20) as i32 +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn copy_special_str( + result: *mut u8, + sign: bool, + exponent: bool, + mantissa: bool, +) -> usize { + if mantissa { + ptr::copy_nonoverlapping(b"NaN".as_ptr(), result, 3); + return 3; + } + if sign { + *result = b'-'; + } + if exponent { + ptr::copy_nonoverlapping(b"Infinity".as_ptr(), result.offset(sign as isize), 8); + return sign as usize + 8; + } + ptr::copy_nonoverlapping(b"0E0".as_ptr(), result.offset(sign as isize), 3); + sign as usize + 3 +} diff --git a/third_party/rust/ryu/src/d2s.rs b/third_party/rust/ryu/src/d2s.rs new file mode 100644 index 000000000000..e116e862bee4 --- /dev/null +++ b/third_party/rust/ryu/src/d2s.rs @@ -0,0 +1,553 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use core::{mem, ptr}; + +use common::*; +#[cfg(not(feature = "small"))] +use d2s_full_table::*; +#[cfg(feature = "small")] +use d2s_small_table::*; +use digit_table::*; +#[cfg(not(integer128))] +use mulshift128::*; + +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +pub const DOUBLE_MANTISSA_BITS: u32 = 52; +pub const DOUBLE_EXPONENT_BITS: u32 = 11; + +const DOUBLE_POW5_INV_BITCOUNT: i32 = 122; +const DOUBLE_POW5_BITCOUNT: i32 = 121; + +#[cfg_attr(feature = "no-panic", inline)] +fn pow5_factor(mut value: u64) -> u32 { + let mut count = 0u32; + loop { + debug_assert!(value != 0); + let q = value / 5; + let r = value % 5; + if r != 0 { + break; + } + value = q; + count += 1; + } + count +} + +// Returns true if value is divisible by 5^p. +#[cfg_attr(feature = "no-panic", inline)] +fn multiple_of_power_of_5(value: u64, p: u32) -> bool { + // I tried a case distinction on p, but there was no performance difference. + pow5_factor(value) >= p +} + +// Returns true if value is divisible by 2^p. +#[cfg_attr(feature = "no-panic", inline)] +fn multiple_of_power_of_2(value: u64, p: u32) -> bool { + // return __builtin_ctzll(value) >= p; + (value & ((1u64 << p) - 1)) == 0 +} + +#[cfg(integer128)] +#[cfg_attr(feature = "no-panic", inline)] +fn mul_shift(m: u64, mul: &(u64, u64), j: u32) -> u64 { + let b0 = m as u128 * mul.0 as u128; + let b2 = m as u128 * mul.1 as u128; + (((b0 >> 64) + b2) >> (j - 64)) as u64 +} + +#[cfg(integer128)] +#[cfg_attr(feature = "no-panic", inline)] +fn mul_shift_all( + m: u64, + mul: &(u64, u64), + j: u32, + vp: &mut u64, + vm: &mut u64, + mm_shift: u32, +) -> u64 { + *vp = mul_shift(4 * m + 2, mul, j); + *vm = mul_shift(4 * m - 1 - mm_shift as u64, mul, j); + mul_shift(4 * m, mul, j) +} + +#[cfg(not(integer128))] +#[cfg_attr(feature = "no-panic", inline)] +fn mul_shift_all( + mut m: u64, + mul: &(u64, u64), + j: u32, + vp: &mut u64, + vm: &mut u64, + mm_shift: u32, +) -> u64 { + m <<= 1; + // m is maximum 55 bits + let (lo, tmp) = umul128(m, mul.0); + let (mut mid, mut hi) = umul128(m, mul.1); + mid = mid.wrapping_add(tmp); + hi = hi.wrapping_add((mid < tmp) as u64); // overflow into hi + + let lo2 = lo.wrapping_add(mul.0); + let mid2 = mid.wrapping_add(mul.1).wrapping_add((lo2 < lo) as u64); + let hi2 = hi.wrapping_add((mid2 < mid) as u64); + *vp = shiftright128(mid2, hi2, j - 64 - 1); + + if mm_shift == 1 { + let lo3 = lo.wrapping_sub(mul.0); + let mid3 = mid.wrapping_sub(mul.1).wrapping_sub((lo3 > lo) as u64); + let hi3 = hi.wrapping_sub((mid3 > mid) as u64); + *vm = shiftright128(mid3, hi3, j - 64 - 1); + } else { + let lo3 = lo + lo; + let mid3 = mid.wrapping_add(mid).wrapping_add((lo3 < lo) as u64); + let hi3 = hi.wrapping_add(hi).wrapping_add((mid3 < mid) as u64); + let lo4 = lo3.wrapping_sub(mul.0); + let mid4 = mid3.wrapping_sub(mul.1).wrapping_sub((lo4 > lo3) as u64); + let hi4 = hi3.wrapping_sub((mid4 > mid3) as u64); + *vm = shiftright128(mid4, hi4, j - 64); + } + + shiftright128(mid, hi, j - 64 - 1) +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn decimal_length(v: u64) -> u32 { + // This is slightly faster than a loop. + // The average output length is 16.38 digits, so we check high-to-low. + // Function precondition: v is not an 18, 19, or 20-digit number. + // (17 digits are sufficient for round-tripping.) + debug_assert!(v < 100000000000000000); + + if v >= 10000000000000000 { + 17 + } else if v >= 1000000000000000 { + 16 + } else if v >= 100000000000000 { + 15 + } else if v >= 10000000000000 { + 14 + } else if v >= 1000000000000 { + 13 + } else if v >= 100000000000 { + 12 + } else if v >= 10000000000 { + 11 + } else if v >= 1000000000 { + 10 + } else if v >= 100000000 { + 9 + } else if v >= 10000000 { + 8 + } else if v >= 1000000 { + 7 + } else if v >= 100000 { + 6 + } else if v >= 10000 { + 5 + } else if v >= 1000 { + 4 + } else if v >= 100 { + 3 + } else if v >= 10 { + 2 + } else { + 1 + } +} + +// A floating decimal representing m * 10^e. +pub struct FloatingDecimal64 { + pub mantissa: u64, + pub exponent: i32, +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn d2d(ieee_mantissa: u64, ieee_exponent: u32) -> FloatingDecimal64 { + let bias = (1u32 << (DOUBLE_EXPONENT_BITS - 1)) - 1; + + let (e2, m2) = if ieee_exponent == 0 { + ( + // We subtract 2 so that the bounds computation has 2 additional bits. + 1 - bias as i32 - DOUBLE_MANTISSA_BITS as i32 - 2, + ieee_mantissa, + ) + } else { + ( + ieee_exponent as i32 - bias as i32 - DOUBLE_MANTISSA_BITS as i32 - 2, + (1u64 << DOUBLE_MANTISSA_BITS) | ieee_mantissa, + ) + }; + let even = (m2 & 1) == 0; + let accept_bounds = even; + + // Step 2: Determine the interval of legal decimal representations. + let mv = 4 * m2; + // Implicit bool -> int conversion. True is 1, false is 0. + let mm_shift = (ieee_mantissa != 0 || ieee_exponent <= 1) as u32; + // We would compute mp and mm like this: + // uint64_t mp = 4 * m2 + 2; + // uint64_t mm = mv - 1 - mm_shift; + + // Step 3: Convert to a decimal power base using 128-bit arithmetic. + let mut vr: u64; + let mut vp: u64 = unsafe { mem::uninitialized() }; + let mut vm: u64 = unsafe { mem::uninitialized() }; + let e10: i32; + let mut vm_is_trailing_zeros = false; + let mut vr_is_trailing_zeros = false; + if e2 >= 0 { + // I tried special-casing q == 0, but there was no effect on performance. + // This expression is slightly faster than max(0, log10_pow2(e2) - 1). + let q = (log10_pow2(e2) - (e2 > 3) as i32) as u32; + e10 = q as i32; + let k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q as i32) as i32 - 1; + let i = -e2 + q as i32 + k; + vr = mul_shift_all( + m2, + #[cfg(feature = "small")] + unsafe { + &compute_inv_pow5(q) + }, + #[cfg(not(feature = "small"))] + unsafe { + debug_assert!(q < DOUBLE_POW5_INV_SPLIT.len() as u32); + DOUBLE_POW5_INV_SPLIT.get_unchecked(q as usize) + }, + i as u32, + &mut vp, + &mut vm, + mm_shift, + ); + if q <= 21 { + // This should use q <= 22, but I think 21 is also safe. Smaller values + // may still be safe, but it's more difficult to reason about them. + // Only one of mp, mv, and mm can be a multiple of 5, if any. + if mv % 5 == 0 { + vr_is_trailing_zeros = multiple_of_power_of_5(mv, q); + } else if accept_bounds { + // Same as min(e2 + (~mm & 1), pow5_factor(mm)) >= q + // <=> e2 + (~mm & 1) >= q && pow5_factor(mm) >= q + // <=> true && pow5_factor(mm) >= q, since e2 >= q. + vm_is_trailing_zeros = multiple_of_power_of_5(mv - 1 - mm_shift as u64, q); + } else { + // Same as min(e2 + 1, pow5_factor(mp)) >= q. + vp -= multiple_of_power_of_5(mv + 2, q) as u64; + } + } + } else { + // This expression is slightly faster than max(0, log10_pow5(-e2) - 1). + let q = (log10_pow5(-e2) - (-e2 > 1) as i32) as u32; + e10 = q as i32 + e2; + let i = -e2 - q as i32; + let k = pow5bits(i) as i32 - DOUBLE_POW5_BITCOUNT; + let j = q as i32 - k; + vr = mul_shift_all( + m2, + #[cfg(feature = "small")] + unsafe { + &compute_pow5(i as u32) + }, + #[cfg(not(feature = "small"))] + unsafe { + debug_assert!(i < DOUBLE_POW5_SPLIT.len() as i32); + DOUBLE_POW5_SPLIT.get_unchecked(i as usize) + }, + j as u32, + &mut vp, + &mut vm, + mm_shift, + ); + if q <= 1 { + // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. + // mv = 4 * m2, so it always has at least two trailing 0 bits. + vr_is_trailing_zeros = true; + if accept_bounds { + // mm = mv - 1 - mm_shift, so it has 1 trailing 0 bit iff mm_shift == 1. + vm_is_trailing_zeros = mm_shift == 1; + } else { + // mp = mv + 2, so it always has at least one trailing 0 bit. + vp -= 1; + } + } else if q < 63 { + // TODO(ulfjack): Use a tighter bound here. + // We need to compute min(ntz(mv), pow5_factor(mv) - e2) >= q - 1 + // <=> ntz(mv) >= q - 1 && pow5_factor(mv) - e2 >= q - 1 + // <=> ntz(mv) >= q - 1 (e2 is negative and -e2 >= q) + // <=> (mv & ((1 << (q - 1)) - 1)) == 0 + // We also need to make sure that the left shift does not overflow. + vr_is_trailing_zeros = multiple_of_power_of_2(mv, q - 1); + } + } + + // Step 4: Find the shortest decimal representation in the interval of legal representations. + let mut removed = 0u32; + let mut last_removed_digit = 0u8; + // On average, we remove ~2 digits. + let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { + // General case, which happens rarely (~0.7%). + while vp / 10 > vm / 10 { + vm_is_trailing_zeros &= vm - (vm / 10) * 10 == 0; + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + if vm_is_trailing_zeros { + while vm % 10 == 0 { + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + } + if vr_is_trailing_zeros && last_removed_digit == 5 && vr % 2 == 0 { + // Round even if the exact number is .....50..0. + last_removed_digit = 4; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) + as u64 + } else { + // Specialized for the common case (~99.3%). Percentages below are relative to this. + let mut round_up = false; + // Optimization: remove two digits at a time (~86.2%). + if vp / 100 > vm / 100 { + round_up = vr % 100 >= 50; + vr /= 100; + vp /= 100; + vm /= 100; + removed += 2; + } + // Loop iterations below (approximately), without optimization above: + // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02% + // Loop iterations below (approximately), with optimization above: + // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% + while vp / 10 > vm / 10 { + round_up = vr % 10 >= 5; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + (vr == vm || round_up) as u64 + }; + let exp = e10 + removed as i32; + + FloatingDecimal64 { + exponent: exp, + mantissa: output, + } +} + +#[cfg_attr(feature = "no-panic", inline)] +unsafe fn to_chars(v: FloatingDecimal64, sign: bool, result: *mut u8) -> usize { + // Step 5: Print the decimal representation. + let mut index = 0isize; + if sign { + *result.offset(index) = b'-'; + index += 1; + } + + let mut output = v.mantissa; + let olength = decimal_length(output); + + // Print the decimal digits. + // The following code is equivalent to: + // for (uint32_t i = 0; i < olength - 1; ++i) { + // const uint32_t c = output % 10; output /= 10; + // result[index + olength - i] = (char) ('0' + c); + // } + // result[index] = '0' + output % 10; + + let mut i = 0isize; + // We prefer 32-bit operations, even on 64-bit platforms. + // We have at most 17 digits, and uint32_t can store 9 digits. + // If output doesn't fit into uint32_t, we cut off 8 digits, + // so the rest will fit into uint32_t. + if (output >> 32) != 0 { + // Expensive 64-bit division. + let mut output2 = (output - 100000000 * (output / 100000000)) as u32; + output /= 100000000; + + let c = output2 % 10000; + output2 /= 10000; + let d = output2 % 10000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + let d0 = (d % 100) << 1; + let d1 = (d / 100) << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c0 as usize), + result.offset(index + olength as isize - i - 1), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c1 as usize), + result.offset(index + olength as isize - i - 3), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(d0 as usize), + result.offset(index + olength as isize - i - 5), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(d1 as usize), + result.offset(index + olength as isize - i - 7), + 2, + ); + i += 8; + } + let mut output2 = output as u32; + while output2 >= 10000 { + let c = (output2 - 10000 * (output2 / 10000)) as u32; + output2 /= 10000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c0 as usize), + result.offset(index + olength as isize - i - 1), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c1 as usize), + result.offset(index + olength as isize - i - 3), + 2, + ); + i += 4; + } + if output2 >= 100 { + let c = ((output2 % 100) << 1) as u32; + output2 /= 100; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c as usize), + result.offset(index + olength as isize - i - 1), + 2, + ); + i += 2; + } + if output2 >= 10 { + let c = (output2 << 1) as u32; + // We can't use memcpy here: the decimal dot goes between these two digits. + *result.offset(index + olength as isize - i) = *DIGIT_TABLE.get_unchecked(c as usize + 1); + *result.offset(index) = *DIGIT_TABLE.get_unchecked(c as usize); + } else { + *result.offset(index) = b'0' + output2 as u8; + } + + // Print decimal point if needed. + if olength > 1 { + *result.offset(index + 1) = b'.'; + index += olength as isize + 1; + } else { + index += 1; + } + + // Print the exponent. + *result.offset(index) = b'E'; + index += 1; + let mut exp = v.exponent as i32 + olength as i32 - 1; + if exp < 0 { + *result.offset(index) = b'-'; + index += 1; + exp = -exp; + } + + if exp >= 100 { + let c = exp % 10; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked((2 * (exp / 10)) as usize), + result.offset(index), + 2, + ); + *result.offset(index + 2) = b'0' + c as u8; + index += 3; + } else if exp >= 10 { + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked((2 * exp) as usize), + result.offset(index), + 2, + ); + index += 2; + } else { + *result.offset(index) = b'0' + exp as u8; + index += 1; + } + + debug_assert!(index <= 24); + index as usize +} + +/// Print f64 to the given buffer and return number of bytes written. +/// +/// At most 24 bytes will be written. +/// +/// ## Special cases +/// +/// This function represents any NaN as `NaN`, positive infinity as `Infinity`, +/// and negative infinity as `-Infinity`. +/// +/// ## Safety +/// +/// The `result` pointer argument must point to sufficiently many writable bytes +/// to hold Ryū's representation of `f`. +/// +/// ## Example +/// +/// ```rust +/// let f = 1.234f64; +/// +/// unsafe { +/// let mut buffer: [u8; 24] = std::mem::uninitialized(); +/// let n = ryu::raw::d2s_buffered_n(f, &mut buffer[0]); +/// let s = std::str::from_utf8_unchecked(&buffer[..n]); +/// assert_eq!(s, "1.234E0"); +/// } +/// ``` +#[cfg_attr(must_use_return, must_use)] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn d2s_buffered_n(f: f64, result: *mut u8) -> usize { + // Step 1: Decode the floating-point number, and unify normalized and subnormal cases. + let bits = mem::transmute::(f); + + // Decode bits into sign, mantissa, and exponent. + let ieee_sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1); + let ieee_exponent = + (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1); + // Case distinction; exit early for the easy cases. + if ieee_exponent == ((1u32 << DOUBLE_EXPONENT_BITS) - 1) + || (ieee_exponent == 0 && ieee_mantissa == 0) + { + return copy_special_str(result, ieee_sign, ieee_exponent != 0, ieee_mantissa != 0); + } + + let v = d2d(ieee_mantissa, ieee_exponent); + to_chars(v, ieee_sign, result) +} diff --git a/third_party/rust/ryu/src/d2s_full_table.rs b/third_party/rust/ryu/src/d2s_full_table.rs new file mode 100644 index 000000000000..eac50dcfc8cf --- /dev/null +++ b/third_party/rust/ryu/src/d2s_full_table.rs @@ -0,0 +1,643 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +pub static DOUBLE_POW5_INV_SPLIT: [(u64, u64); 292] = [ + (1, 288230376151711744), + (3689348814741910324, 230584300921369395), + (2951479051793528259, 184467440737095516), + (17118578500402463900, 147573952589676412), + (12632330341676300947, 236118324143482260), + (10105864273341040758, 188894659314785808), + (15463389048156653253, 151115727451828646), + (17362724847566824558, 241785163922925834), + (17579528692795369969, 193428131138340667), + (6684925324752475329, 154742504910672534), + (18074578149087781173, 247588007857076054), + (18149011334012135262, 198070406285660843), + (3451162622983977240, 158456325028528675), + (5521860196774363583, 253530120045645880), + (4417488157419490867, 202824096036516704), + (7223339340677503017, 162259276829213363), + (7867994130342094503, 259614842926741381), + (2605046489531765280, 207691874341393105), + (2084037191625412224, 166153499473114484), + (10713157136084480204, 265845599156983174), + (12259874523609494487, 212676479325586539), + (13497248433629505913, 170141183460469231), + (14216899864323388813, 272225893536750770), + (11373519891458711051, 217780714829400616), + (5409467098425058518, 174224571863520493), + (4965798542738183305, 278759314981632789), + (7661987648932456967, 223007451985306231), + (2440241304404055250, 178405961588244985), + (3904386087046488400, 285449538541191976), + (17880904128604832013, 228359630832953580), + (14304723302883865611, 182687704666362864), + (15133127457049002812, 146150163733090291), + (16834306301794583852, 233840261972944466), + (9778096226693756759, 187072209578355573), + (15201174610838826053, 149657767662684458), + (2185786488890659746, 239452428260295134), + (5437978005854438120, 191561942608236107), + (15418428848909281466, 153249554086588885), + (6222742084545298729, 245199286538542217), + (16046240111861969953, 196159429230833773), + (1768945645263844993, 156927543384667019), + (10209010661905972635, 251084069415467230), + (8167208529524778108, 200867255532373784), + (10223115638361732810, 160693804425899027), + (1599589762411131202, 257110087081438444), + (4969020624670815285, 205688069665150755), + (3975216499736652228, 164550455732120604), + (13739044029062464211, 263280729171392966), + (7301886408508061046, 210624583337114373), + (13220206756290269483, 168499666669691498), + (17462981995322520850, 269599466671506397), + (6591687966774196033, 215679573337205118), + (12652048002903177473, 172543658669764094), + (9175230360419352987, 276069853871622551), + (3650835473593572067, 220855883097298041), + (17678063637842498946, 176684706477838432), + (13527506561580357021, 282695530364541492), + (3443307619780464970, 226156424291633194), + (6443994910566282300, 180925139433306555), + (5155195928453025840, 144740111546645244), + (15627011115008661990, 231584178474632390), + (12501608892006929592, 185267342779705912), + (2622589484121723027, 148213874223764730), + (4196143174594756843, 237142198758023568), + (10735612169159626121, 189713759006418854), + (12277838550069611220, 151771007205135083), + (15955192865369467629, 242833611528216133), + (1696107848069843133, 194266889222572907), + (12424932722681605476, 155413511378058325), + (1433148282581017146, 248661618204893321), + (15903913885032455010, 198929294563914656), + (9033782293284053685, 159143435651131725), + (14454051669254485895, 254629497041810760), + (11563241335403588716, 203703597633448608), + (16629290697806691620, 162962878106758886), + (781423413297334329, 260740604970814219), + (4314487545379777786, 208592483976651375), + (3451590036303822229, 166873987181321100), + (5522544058086115566, 266998379490113760), + (4418035246468892453, 213598703592091008), + (10913125826658934609, 170878962873672806), + (10082303693170474728, 273406340597876490), + (8065842954536379782, 218725072478301192), + (17520720807854834795, 174980057982640953), + (5897060404116273733, 279968092772225526), + (1028299508551108663, 223974474217780421), + (15580034865808528224, 179179579374224336), + (17549358155809824511, 286687326998758938), + (2971440080422128639, 229349861599007151), + (17134547323305344204, 183479889279205720), + (13707637858644275364, 146783911423364576), + (14553522944347019935, 234854258277383322), + (4264120725993795302, 187883406621906658), + (10789994210278856888, 150306725297525326), + (9885293106962350374, 240490760476040522), + (529536856086059653, 192392608380832418), + (7802327114352668369, 153914086704665934), + (1415676938738538420, 246262538727465495), + (1132541550990830736, 197010030981972396), + (15663428499760305882, 157608024785577916), + (17682787970132668764, 252172839656924666), + (10456881561364224688, 201738271725539733), + (15744202878575200397, 161390617380431786), + (17812026976236499989, 258224987808690858), + (3181575136763469022, 206579990246952687), + (13613306553636506187, 165263992197562149), + (10713244041592678929, 264422387516099439), + (12259944048016053467, 211537910012879551), + (6118606423670932450, 169230328010303641), + (2411072648389671274, 270768524816485826), + (16686253377679378312, 216614819853188660), + (13349002702143502650, 173291855882550928), + (17669055508687693916, 277266969412081485), + (14135244406950155133, 221813575529665188), + (240149081334393137, 177450860423732151), + (11452284974360759988, 283921376677971441), + (5472479164746697667, 227137101342377153), + (11756680961281178780, 181709681073901722), + (2026647139541122378, 145367744859121378), + (18000030682233437097, 232588391774594204), + (18089373360528660001, 186070713419675363), + (3403452244197197031, 148856570735740291), + (16513570034941246220, 238170513177184465), + (13210856027952996976, 190536410541747572), + (3189987192878576934, 152429128433398058), + (1414630693863812771, 243886605493436893), + (8510402184574870864, 195109284394749514), + (10497670562401807014, 156087427515799611), + (9417575270359070576, 249739884025279378), + (14912757845771077107, 199791907220223502), + (4551508647133041040, 159833525776178802), + (10971762650154775986, 255733641241886083), + (16156107749607641435, 204586912993508866), + (9235537384944202825, 163669530394807093), + (11087511001168814197, 261871248631691349), + (12559357615676961681, 209496998905353079), + (13736834907283479668, 167597599124282463), + (18289587036911657145, 268156158598851941), + (10942320814787415393, 214524926879081553), + (16132554281313752961, 171619941503265242), + (11054691591134363444, 274591906405224388), + (16222450902391311402, 219673525124179510), + (12977960721913049122, 175738820099343608), + (17075388340318968271, 281182112158949773), + (2592264228029443648, 224945689727159819), + (5763160197165465241, 179956551781727855), + (9221056315464744386, 287930482850764568), + (14755542681855616155, 230344386280611654), + (15493782960226403247, 184275509024489323), + (1326979923955391628, 147420407219591459), + (9501865507812447252, 235872651551346334), + (11290841220991868125, 188698121241077067), + (1653975347309673853, 150958496992861654), + (10025058185179298811, 241533595188578646), + (4330697733401528726, 193226876150862917), + (14532604630946953951, 154581500920690333), + (1116074521063664381, 247330401473104534), + (4582208431592841828, 197864321178483627), + (14733813189500004432, 158291456942786901), + (16195403473716186445, 253266331108459042), + (5577625149489128510, 202613064886767234), + (8151448934333213131, 162090451909413787), + (16731667109675051333, 259344723055062059), + (17074682502481951390, 207475778444049647), + (6281048372501740465, 165980622755239718), + (6360328581260874421, 265568996408383549), + (8777611679750609860, 212455197126706839), + (10711438158542398211, 169964157701365471), + (9759603424184016492, 271942652322184754), + (11497031554089123517, 217554121857747803), + (16576322872755119460, 174043297486198242), + (11764721337440549842, 278469275977917188), + (16790474699436260520, 222775420782333750), + (13432379759549008416, 178220336625867000), + (3045063541568861850, 285152538601387201), + (17193446092222730773, 228122030881109760), + (13754756873778184618, 182497624704887808), + (18382503128506368341, 145998099763910246), + (3586563302416817083, 233596959622256395), + (2869250641933453667, 186877567697805116), + (17052795772514404226, 149502054158244092), + (12527077977055405469, 239203286653190548), + (17400360011128145022, 191362629322552438), + (2852241564676785048, 153090103458041951), + (15631632947708587046, 244944165532867121), + (8815957543424959314, 195955332426293697), + (18120812478965698421, 156764265941034957), + (14235904707377476180, 250822825505655932), + (4010026136418160298, 200658260404524746), + (17965416168102169531, 160526608323619796), + (2919224165770098987, 256842573317791675), + (2335379332616079190, 205474058654233340), + (1868303466092863352, 164379246923386672), + (6678634360490491686, 263006795077418675), + (5342907488392393349, 210405436061934940), + (4274325990713914679, 168324348849547952), + (10528270399884173809, 269318958159276723), + (15801313949391159694, 215455166527421378), + (1573004715287196786, 172364133221937103), + (17274202803427156150, 275782613155099364), + (17508711057483635243, 220626090524079491), + (10317620031244997871, 176500872419263593), + (12818843235250086271, 282401395870821749), + (13944423402941979340, 225921116696657399), + (14844887537095493795, 180736893357325919), + (15565258844418305359, 144589514685860735), + (6457670077359736959, 231343223497377177), + (16234182506113520537, 185074578797901741), + (9297997190148906106, 148059663038321393), + (11187446689496339446, 236895460861314229), + (12639306166338981880, 189516368689051383), + (17490142562555006151, 151613094951241106), + (2158786396894637579, 242580951921985771), + (16484424376483351356, 194064761537588616), + (9498190686444770762, 155251809230070893), + (11507756283569722895, 248402894768113429), + (12895553841597688639, 198722315814490743), + (17695140702761971558, 158977852651592594), + (17244178680193423523, 254364564242548151), + (10105994129412828495, 203491651394038521), + (4395446488788352473, 162793321115230817), + (10722063196803274280, 260469313784369307), + (1198952927958798777, 208375451027495446), + (15716557601334680315, 166700360821996356), + (17767794532651667857, 266720577315194170), + (14214235626121334286, 213376461852155336), + (7682039686155157106, 170701169481724269), + (1223217053622520399, 273121871170758831), + (15735968901865657612, 218497496936607064), + (16278123936234436413, 174797997549285651), + (219556594781725998, 279676796078857043), + (7554342905309201445, 223741436863085634), + (9732823138989271479, 178993149490468507), + (815121763415193074, 286389039184749612), + (11720143854957885429, 229111231347799689), + (13065463898708218666, 183288985078239751), + (6763022304224664610, 146631188062591801), + (3442138057275642729, 234609900900146882), + (13821756890046245153, 187687920720117505), + (11057405512036996122, 150150336576094004), + (6623802375033462826, 240240538521750407), + (16367088344252501231, 192192430817400325), + (13093670675402000985, 153753944653920260), + (2503129006933649959, 246006311446272417), + (13070549649772650937, 196805049157017933), + (17835137349301941396, 157444039325614346), + (2710778055689733971, 251910462920982955), + (2168622444551787177, 201528370336786364), + (5424246770383340065, 161222696269429091), + (1300097203129523457, 257956314031086546), + (15797473021471260058, 206365051224869236), + (8948629602435097724, 165092040979895389), + (3249760919670425388, 264147265567832623), + (9978506365220160957, 211317812454266098), + (15361502721659949412, 169054249963412878), + (2442311466204457120, 270486799941460606), + (16711244431931206989, 216389439953168484), + (17058344360286875914, 173111551962534787), + (12535955717491360170, 276978483140055660), + (10028764573993088136, 221582786512044528), + (15401709288678291155, 177266229209635622), + (9885339602917624555, 283625966735416996), + (4218922867592189321, 226900773388333597), + (14443184738299482427, 181520618710666877), + (4175850161155765295, 145216494968533502), + (10370709072591134795, 232346391949653603), + (15675264887556728482, 185877113559722882), + (5161514280561562140, 148701690847778306), + (879725219414678777, 237922705356445290), + (703780175531743021, 190338164285156232), + (11631070584651125387, 152270531428124985), + (162968861732249003, 243632850284999977), + (11198421533611530172, 194906280227999981), + (5269388412147313814, 155925024182399985), + (8431021459435702103, 249480038691839976), + (3055468352806651359, 199584030953471981), + (17201769941212962380, 159667224762777584), + (16454785461715008838, 255467559620444135), + (13163828369372007071, 204374047696355308), + (17909760324981426303, 163499238157084246), + (2830174816776909822, 261598781051334795), + (2264139853421527858, 209279024841067836), + (16568707141704863579, 167423219872854268), + (4373838538276319787, 267877151796566830), + (3499070830621055830, 214301721437253464), + (6488605479238754987, 171441377149802771), + (3003071137298187333, 274306203439684434), + (6091805724580460189, 219444962751747547), + (15941491023890099121, 175555970201398037), + (10748990379256517301, 280889552322236860), + (8599192303405213841, 224711641857789488), + (14258051472207991719, 179769313486231590), +]; + +pub static DOUBLE_POW5_SPLIT: [(u64, u64); 326] = [ + (0, 72057594037927936), + (0, 90071992547409920), + (0, 112589990684262400), + (0, 140737488355328000), + (0, 87960930222080000), + (0, 109951162777600000), + (0, 137438953472000000), + (0, 85899345920000000), + (0, 107374182400000000), + (0, 134217728000000000), + (0, 83886080000000000), + (0, 104857600000000000), + (0, 131072000000000000), + (0, 81920000000000000), + (0, 102400000000000000), + (0, 128000000000000000), + (0, 80000000000000000), + (0, 100000000000000000), + (0, 125000000000000000), + (0, 78125000000000000), + (0, 97656250000000000), + (0, 122070312500000000), + (0, 76293945312500000), + (0, 95367431640625000), + (0, 119209289550781250), + (4611686018427387904, 74505805969238281), + (10376293541461622784, 93132257461547851), + (8358680908399640576, 116415321826934814), + (612489549322387456, 72759576141834259), + (14600669991935148032, 90949470177292823), + (13639151471491547136, 113686837721616029), + (3213881284082270208, 142108547152020037), + (4314518811765112832, 88817841970012523), + (781462496279003136, 111022302462515654), + (10200200157203529728, 138777878078144567), + (13292654125893287936, 86736173798840354), + (7392445620511834112, 108420217248550443), + (4628871007212404736, 135525271560688054), + (16728102434789916672, 84703294725430033), + (7075069988205232128, 105879118406787542), + (18067209522111315968, 132348898008484427), + (8986162942105878528, 82718061255302767), + (6621017659204960256, 103397576569128459), + (3664586055578812416, 129246970711410574), + (16125424340018921472, 80779356694631608), + (1710036351314100224, 100974195868289511), + (15972603494424788992, 126217744835361888), + (9982877184015493120, 78886090522101180), + (12478596480019366400, 98607613152626475), + (10986559581596820096, 123259516440783094), + (2254913720070624656, 77037197775489434), + (12042014186943056628, 96296497219361792), + (15052517733678820785, 120370621524202240), + (9407823583549262990, 75231638452626400), + (11759779479436578738, 94039548065783000), + (14699724349295723422, 117549435082228750), + (4575641699882439235, 73468396926392969), + (10331238143280436948, 91835496157991211), + (8302361660673158281, 114794370197489014), + (1154580038986672043, 143492962746861268), + (9944984561221445835, 89683101716788292), + (12431230701526807293, 112103877145985365), + (1703980321626345405, 140129846432481707), + (17205888765512323542, 87581154020301066), + (12283988920035628619, 109476442525376333), + (1519928094762372062, 136845553156720417), + (12479170105294952299, 85528470722950260), + (15598962631618690374, 106910588403687825), + (5663645234241199255, 133638235504609782), + (17374836326682913246, 83523897190381113), + (7883487353071477846, 104404871487976392), + (9854359191339347308, 130506089359970490), + (10770660513014479971, 81566305849981556), + (13463325641268099964, 101957882312476945), + (2994098996302961243, 127447352890596182), + (15706369927971514489, 79654595556622613), + (5797904354682229399, 99568244445778267), + (2635694424925398845, 124460305557222834), + (6258995034005762182, 77787690973264271), + (3212057774079814824, 97234613716580339), + (17850130272881932242, 121543267145725423), + (18073860448192289507, 75964541966078389), + (8757267504958198172, 94955677457597987), + (6334898362770359811, 118694596821997484), + (13182683513586250689, 74184123013748427), + (11866668373555425458, 92730153767185534), + (5609963430089506015, 115912692208981918), + (17341285199088104971, 72445432630613698), + (12453234462005355406, 90556790788267123), + (10954857059079306353, 113195988485333904), + (13693571323849132942, 141494985606667380), + (17781854114260483896, 88434366004167112), + (3780573569116053255, 110542957505208891), + (114030942967678664, 138178696881511114), + (4682955357782187069, 86361685550944446), + (15077066234082509644, 107952106938680557), + (5011274737320973344, 134940133673350697), + (14661261756894078100, 84337583545844185), + (4491519140835433913, 105421979432305232), + (5614398926044292391, 131777474290381540), + (12732371365632458552, 82360921431488462), + (6692092170185797382, 102951151789360578), + (17588487249587022536, 128688939736700722), + (15604490549419276989, 80430587335437951), + (14893927168346708332, 100538234169297439), + (14005722942005997511, 125672792711621799), + (15671105866394830300, 78545495444763624), + (1142138259283986260, 98181869305954531), + (15262730879387146537, 122727336632443163), + (7233363790403272633, 76704585395276977), + (13653390756431478696, 95880731744096221), + (3231680390257184658, 119850914680120277), + (4325643253124434363, 74906821675075173), + (10018740084832930858, 93633527093843966), + (3300053069186387764, 117041908867304958), + (15897591223523656064, 73151193042065598), + (10648616992549794273, 91438991302581998), + (4087399203832467033, 114298739128227498), + (14332621041645359599, 142873423910284372), + (18181260187883125557, 89295889943927732), + (4279831161144355331, 111619862429909666), + (14573160988285219972, 139524828037387082), + (13719911636105650386, 87203017523366926), + (7926517508277287175, 109003771904208658), + (684774848491833161, 136254714880260823), + (7345513307948477581, 85159196800163014), + (18405263671790372785, 106448996000203767), + (18394893571310578077, 133061245000254709), + (13802651491282805250, 83163278125159193), + (3418256308821342851, 103954097656448992), + (4272820386026678563, 129942622070561240), + (2670512741266674102, 81214138794100775), + (17173198981865506339, 101517673492625968), + (3019754653622331308, 126897091865782461), + (4193189667727651020, 79310682416114038), + (14464859121514339583, 99138353020142547), + (13469387883465536574, 123922941275178184), + (8418367427165960359, 77451838296986365), + (15134645302384838353, 96814797871232956), + (471562554271496325, 121018497339041196), + (9518098633274461011, 75636560836900747), + (7285937273165688360, 94545701046125934), + (18330793628311886258, 118182126307657417), + (4539216990053847055, 73863828942285886), + (14897393274422084627, 92329786177857357), + (4786683537745442072, 115412232722321697), + (14520892257159371055, 72132645451451060), + (18151115321449213818, 90165806814313825), + (8853836096529353561, 112707258517892282), + (1843923083806916143, 140884073147365353), + (12681666973447792349, 88052545717103345), + (2017025661527576725, 110065682146379182), + (11744654113764246714, 137582102682973977), + (422879793461572340, 85988814176858736), + (528599741826965425, 107486017721073420), + (660749677283706782, 134357522151341775), + (7330497575943398595, 83973451344588609), + (13774807988356636147, 104966814180735761), + (3383451930163631472, 131208517725919702), + (15949715511634433382, 82005323578699813), + (6102086334260878016, 102506654473374767), + (3015921899398709616, 128133318091718459), + (18025852251620051174, 80083323807324036), + (4085571240815512351, 100104154759155046), + (14330336087874166247, 125130193448943807), + (15873989082562435760, 78206370905589879), + (15230800334775656796, 97757963631987349), + (5203442363187407284, 122197454539984187), + (946308467778435600, 76373409087490117), + (5794571603150432404, 95466761359362646), + (16466586540792816313, 119333451699203307), + (7985773578781816244, 74583407312002067), + (5370530955049882401, 93229259140002584), + (6713163693812353001, 116536573925003230), + (18030785363914884337, 72835358703127018), + (13315109668038829614, 91044198378908773), + (2808829029766373305, 113805247973635967), + (17346094342490130344, 142256559967044958), + (6229622945628943561, 88910349979403099), + (3175342663608791547, 111137937474253874), + (13192550366365765242, 138922421842817342), + (3633657960551215372, 86826513651760839), + (18377130505971182927, 108533142064701048), + (4524669058754427043, 135666427580876311), + (9745447189362598758, 84791517238047694), + (2958436949848472639, 105989396547559618), + (12921418224165366607, 132486745684449522), + (12687572408530742033, 82804216052780951), + (11247779492236039638, 103505270065976189), + (224666310012885835, 129381587582470237), + (2446259452971747599, 80863492239043898), + (12281196353069460307, 101079365298804872), + (15351495441336825384, 126349206623506090), + (14206370669262903769, 78968254139691306), + (8534591299723853903, 98710317674614133), + (15279925143082205283, 123387897093267666), + (14161639232853766206, 77117435683292291), + (13090363022639819853, 96396794604115364), + (16362953778299774816, 120495993255144205), + (12532689120651053212, 75309995784465128), + (15665861400813816515, 94137494730581410), + (10358954714162494836, 117671868413226763), + (4168503687137865320, 73544917758266727), + (598943590494943747, 91931147197833409), + (5360365506546067587, 114913933997291761), + (11312142901609972388, 143642417496614701), + (9375932322719926695, 89776510935384188), + (11719915403399908368, 112220638669230235), + (10038208235822497557, 140275798336537794), + (10885566165816448877, 87672373960336121), + (18218643725697949000, 109590467450420151), + (18161618638695048346, 136988084313025189), + (13656854658398099168, 85617552695640743), + (12459382304570236056, 107021940869550929), + (1739169825430631358, 133777426086938662), + (14922039196176308311, 83610891304336663), + (14040862976792997485, 104513614130420829), + (3716020665709083144, 130642017663026037), + (4628355925281870917, 81651261039391273), + (10397130925029726550, 102064076299239091), + (8384727637859770284, 127580095374048864), + (5240454773662356427, 79737559608780540), + (6550568467077945534, 99671949510975675), + (3576524565420044014, 124589936888719594), + (6847013871814915412, 77868710555449746), + (17782139376623420074, 97335888194312182), + (13004302183924499284, 121669860242890228), + (17351060901807587860, 76043662651806392), + (3242082053549933210, 95054578314757991), + (17887660622219580224, 118818222893447488), + (11179787888887237640, 74261389308404680), + (13974734861109047050, 92826736635505850), + (8245046539531533005, 116033420794382313), + (16682369133275677888, 72520887996488945), + (7017903361312433648, 90651109995611182), + (17995751238495317868, 113313887494513977), + (8659630992836983623, 141642359368142472), + (5412269370523114764, 88526474605089045), + (11377022731581281359, 110658093256361306), + (4997906377621825891, 138322616570451633), + (14652906532082110942, 86451635356532270), + (9092761128247862869, 108064544195665338), + (2142579373455052779, 135080680244581673), + (12868327154477877747, 84425425152863545), + (2250350887815183471, 105531781441079432), + (2812938609768979339, 131914726801349290), + (6369772649532999991, 82446704250843306), + (17185587848771025797, 103058380313554132), + (3035240737254230630, 128822975391942666), + (6508711479211282048, 80514359619964166), + (17359261385868878368, 100642949524955207), + (17087390713908710056, 125803686906194009), + (3762090168551861929, 78627304316371256), + (4702612710689827411, 98284130395464070), + (15101637925217060072, 122855162994330087), + (16356052730901744401, 76784476871456304), + (1998321839917628885, 95980596089320381), + (7109588318324424010, 119975745111650476), + (13666864735807540814, 74984840694781547), + (12471894901332038114, 93731050868476934), + (6366496589810271835, 117163813585596168), + (3979060368631419896, 73227383490997605), + (9585511479216662775, 91534229363747006), + (2758517312166052660, 114417786704683758), + (12671518677062341634, 143022233380854697), + (1002170145522881665, 89388895863034186), + (10476084718758377889, 111736119828792732), + (13095105898447972362, 139670149785990915), + (5878598177316288774, 87293843616244322), + (16571619758500136775, 109117304520305402), + (11491152661270395161, 136396630650381753), + (264441385652915120, 85247894156488596), + (330551732066143900, 106559867695610745), + (5024875683510067779, 133199834619513431), + (10058076329834874218, 83249896637195894), + (3349223375438816964, 104062370796494868), + (4186529219298521205, 130077963495618585), + (14145795808130045513, 81298727184761615), + (13070558741735168987, 101623408980952019), + (11726512408741573330, 127029261226190024), + (7329070255463483331, 79393288266368765), + (13773023837756742068, 99241610332960956), + (17216279797195927585, 124052012916201195), + (8454331864033760789, 77532508072625747), + (5956228811614813082, 96915635090782184), + (7445286014518516353, 121144543863477730), + (9264989777501460624, 75715339914673581), + (16192923240304213684, 94644174893341976), + (1794409976670715490, 118305218616677471), + (8039035263060279037, 73940761635423419), + (5437108060397960892, 92425952044279274), + (16019757112352226923, 115532440055349092), + (788976158365366019, 72207775034593183), + (14821278253238871236, 90259718793241478), + (9303225779693813237, 112824648491551848), + (11629032224617266546, 141030810614439810), + (11879831158813179495, 88144256634024881), + (1014730893234310657, 110180320792531102), + (10491785653397664129, 137725400990663877), + (8863209042587234033, 86078375619164923), + (6467325284806654637, 107597969523956154), + (17307528642863094104, 134497461904945192), + (10817205401789433815, 84060913690590745), + (18133192770664180173, 105076142113238431), + (18054804944902837312, 131345177641548039), + (18201782118205355176, 82090736025967524), + (4305483574047142354, 102613420032459406), + (14605226504413703751, 128266775040574257), + (2210737537617482988, 80166734400358911), + (16598479977304017447, 100208418000448638), + (11524727934775246001, 125260522500560798), + (2591268940807140847, 78287826562850499), + (17074144231291089770, 97859783203563123), + (16730994270686474309, 122324729004453904), + (10456871419179046443, 76452955627783690), + (3847717237119032246, 95566194534729613), + (9421332564826178211, 119457743168412016), + (5888332853016361382, 74661089480257510), + (16583788103125227536, 93326361850321887), + (16118049110479146516, 116657952312902359), + (16991309721690548428, 72911220195563974), + (12015765115258409727, 91139025244454968), + (15019706394073012159, 113923781555568710), + (9551260955736489391, 142404726944460888), + (5969538097335305869, 89002954340288055), + (2850236603241744433, 111253692925360069), +]; diff --git a/third_party/rust/ryu/src/d2s_small_table.rs b/third_party/rust/ryu/src/d2s_small_table.rs new file mode 100644 index 000000000000..c6e3f65e2fd5 --- /dev/null +++ b/third_party/rust/ryu/src/d2s_small_table.rs @@ -0,0 +1,206 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use common::*; +#[cfg(not(integer128))] +use mulshift128::*; + +pub static DOUBLE_POW5_TABLE: [u64; 26] = [ + 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, +]; + +pub static DOUBLE_POW5_SPLIT2: [(u64, u64); 13] = [ + (0, 72057594037927936), + (10376293541461622784, 93132257461547851), + (15052517733678820785, 120370621524202240), + (6258995034005762182, 77787690973264271), + (14893927168346708332, 100538234169297439), + (4272820386026678563, 129942622070561240), + (7330497575943398595, 83973451344588609), + (18377130505971182927, 108533142064701048), + (10038208235822497557, 140275798336537794), + (7017903361312433648, 90651109995611182), + (6366496589810271835, 117163813585596168), + (9264989777501460624, 75715339914673581), + (17074144231291089770, 97859783203563123), +]; + +// Unfortunately, the results are sometimes off by one. We use an additional +// lookup table to store those cases and adjust the result. +pub static POW5_OFFSETS: [u32; 13] = [ + 0x00000000, 0x00000000, 0x00000000, 0x033c55be, 0x03db77d8, 0x0265ffb2, 0x00000800, 0x01a8ff56, + 0x00000000, 0x0037a200, 0x00004000, 0x03fffffc, 0x00003ffe, +]; + +pub static DOUBLE_POW5_INV_SPLIT2: [(u64, u64); 13] = [ + (1, 288230376151711744), + (7661987648932456967, 223007451985306231), + (12652048002903177473, 172543658669764094), + (5522544058086115566, 266998379490113760), + (3181575136763469022, 206579990246952687), + (4551508647133041040, 159833525776178802), + (1116074521063664381, 247330401473104534), + (17400360011128145022, 191362629322552438), + (9297997190148906106, 148059663038321393), + (11720143854957885429, 229111231347799689), + (15401709288678291155, 177266229209635622), + (3003071137298187333, 274306203439684434), + (17516772882021341108, 212234145163966538), +]; + +pub static POW5_INV_OFFSETS: [u32; 20] = [ + 0x51505404, 0x55054514, 0x45555545, 0x05511411, 0x00505010, 0x00000004, 0x00000000, 0x00000000, + 0x55555040, 0x00505051, 0x00050040, 0x55554000, 0x51659559, 0x00001000, 0x15000010, 0x55455555, + 0x41404051, 0x00001010, 0x00000014, 0x00000000, +]; + +// Computes 5^i in the form required by Ryu. +#[cfg(integer128)] +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_pow5(i: u32) -> (u64, u64) { + let base = i / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = i - base2; + debug_assert!(base < DOUBLE_POW5_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_SPLIT2.get_unchecked(base as usize); + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); + let b0 = m as u128 * mul.0 as u128; + let b2 = m as u128 * mul.1 as u128; + let delta = pow5bits(i as i32) - pow5bits(base2 as i32); + debug_assert!(base < POW5_OFFSETS.len() as u32); + let shifted_sum = (b0 >> delta) + + (b2 << (64 - delta)) + + ((*POW5_OFFSETS.get_unchecked(base as usize) >> offset) & 1) as u128; + (shifted_sum as u64, (shifted_sum >> 64) as u64) +} + +// Computes 5^-i in the form required by Ryu. +#[cfg(integer128)] +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_inv_pow5(i: u32) -> (u64, u64) { + let base = (i + DOUBLE_POW5_TABLE.len() as u32 - 1) / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = base2 - i; + debug_assert!(base < DOUBLE_POW5_INV_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_INV_SPLIT2.get_unchecked(base as usize); // 1/5^base2 + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); // 5^offset + let b0 = m as u128 * (mul.0 - 1) as u128; + let b2 = m as u128 * mul.1 as u128; // 1/5^base2 * 5^offset = 1/5^(base2-offset) = 1/5^i + let delta = pow5bits(base2 as i32) - pow5bits(i as i32); + debug_assert!(base < POW5_INV_OFFSETS.len() as u32); + let shifted_sum = ((b0 >> delta) + (b2 << (64 - delta))) + + 1 + + ((*POW5_INV_OFFSETS.get_unchecked((i / 16) as usize) >> ((i % 16) << 1)) & 3) as u128; + (shifted_sum as u64, (shifted_sum >> 64) as u64) +} + +// Computes 5^i in the form required by Ryu, and stores it in the given pointer. +#[cfg(not(integer128))] +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_pow5(i: u32) -> (u64, u64) { + let base = i / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = i - base2; + debug_assert!(base < DOUBLE_POW5_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_SPLIT2.get_unchecked(base as usize); + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); + let (low1, mut high1) = umul128(m, mul.1); + let (low0, high0) = umul128(m, mul.0); + let sum = high0 + low1; + if sum < high0 { + high1 += 1; // overflow into high1 + } + // high1 | sum | low0 + let delta = pow5bits(i as i32) - pow5bits(base2 as i32); + debug_assert!(base < POW5_OFFSETS.len() as u32); + ( + shiftright128(low0, sum, delta) + + ((*POW5_OFFSETS.get_unchecked(base as usize) >> offset) & 1) as u64, + shiftright128(sum, high1, delta), + ) +} + +// Computes 5^-i in the form required by Ryu, and stores it in the given pointer. +#[cfg(not(integer128))] +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn compute_inv_pow5(i: u32) -> (u64, u64) { + let base = (i + DOUBLE_POW5_TABLE.len() as u32 - 1) / DOUBLE_POW5_TABLE.len() as u32; + let base2 = base * DOUBLE_POW5_TABLE.len() as u32; + let offset = base2 - i; + debug_assert!(base < DOUBLE_POW5_INV_SPLIT2.len() as u32); + let mul = *DOUBLE_POW5_INV_SPLIT2.get_unchecked(base as usize); // 1/5^base2 + if offset == 0 { + return mul; + } + debug_assert!(offset < DOUBLE_POW5_TABLE.len() as u32); + let m = *DOUBLE_POW5_TABLE.get_unchecked(offset as usize); + let (low1, mut high1) = umul128(m, mul.1); + let (low0, high0) = umul128(m, mul.0 - 1); + let sum = high0 + low1; + if sum < high0 { + high1 += 1; // overflow into high1 + } + // high1 | sum | low0 + let delta = pow5bits(base2 as i32) - pow5bits(i as i32); + debug_assert!(base < POW5_INV_OFFSETS.len() as u32); + ( + shiftright128(low0, sum, delta) + + 1 + + ((*POW5_INV_OFFSETS.get_unchecked((i / 16) as usize) >> ((i % 16) << 1)) & 3) as u64, + shiftright128(sum, high1, delta), + ) +} diff --git a/third_party/rust/ryu/src/digit_table.rs b/third_party/rust/ryu/src/digit_table.rs new file mode 100644 index 000000000000..d871f03f7745 --- /dev/null +++ b/third_party/rust/ryu/src/digit_table.rs @@ -0,0 +1,28 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +// A table of all two-digit numbers. This is used to speed up decimal digit +// generation by copying pairs of digits into the final output. +pub static DIGIT_TABLE: [u8; 200] = *b"\ + 0001020304050607080910111213141516171819\ + 2021222324252627282930313233343536373839\ + 4041424344454647484950515253545556575859\ + 6061626364656667686970717273747576777879\ + 8081828384858687888990919293949596979899"; diff --git a/third_party/rust/ryu/src/f2s.rs b/third_party/rust/ryu/src/f2s.rs new file mode 100644 index 000000000000..a6569b5dd53c --- /dev/null +++ b/third_party/rust/ryu/src/f2s.rs @@ -0,0 +1,494 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +use core::{mem, ptr}; + +use common::*; +use digit_table::*; + +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +pub const FLOAT_MANTISSA_BITS: u32 = 23; +pub const FLOAT_EXPONENT_BITS: u32 = 8; + +const FLOAT_POW5_INV_BITCOUNT: i32 = 59; +const FLOAT_POW5_BITCOUNT: i32 = 61; + +// This table is generated by PrintFloatLookupTable. +static FLOAT_POW5_INV_SPLIT: [u64; 32] = [ + 576460752303423489, + 461168601842738791, + 368934881474191033, + 295147905179352826, + 472236648286964522, + 377789318629571618, + 302231454903657294, + 483570327845851670, + 386856262276681336, + 309485009821345069, + 495176015714152110, + 396140812571321688, + 316912650057057351, + 507060240091291761, + 405648192073033409, + 324518553658426727, + 519229685853482763, + 415383748682786211, + 332306998946228969, + 531691198313966350, + 425352958651173080, + 340282366920938464, + 544451787073501542, + 435561429658801234, + 348449143727040987, + 557518629963265579, + 446014903970612463, + 356811923176489971, + 570899077082383953, + 456719261665907162, + 365375409332725730, + 1 << 63, +]; + +static FLOAT_POW5_SPLIT: [u64; 47] = [ + 1152921504606846976, + 1441151880758558720, + 1801439850948198400, + 2251799813685248000, + 1407374883553280000, + 1759218604441600000, + 2199023255552000000, + 1374389534720000000, + 1717986918400000000, + 2147483648000000000, + 1342177280000000000, + 1677721600000000000, + 2097152000000000000, + 1310720000000000000, + 1638400000000000000, + 2048000000000000000, + 1280000000000000000, + 1600000000000000000, + 2000000000000000000, + 1250000000000000000, + 1562500000000000000, + 1953125000000000000, + 1220703125000000000, + 1525878906250000000, + 1907348632812500000, + 1192092895507812500, + 1490116119384765625, + 1862645149230957031, + 1164153218269348144, + 1455191522836685180, + 1818989403545856475, + 2273736754432320594, + 1421085471520200371, + 1776356839400250464, + 2220446049250313080, + 1387778780781445675, + 1734723475976807094, + 2168404344971008868, + 1355252715606880542, + 1694065894508600678, + 2117582368135750847, + 1323488980084844279, + 1654361225106055349, + 2067951531382569187, + 1292469707114105741, + 1615587133892632177, + 2019483917365790221, +]; + +#[cfg_attr(feature = "no-panic", inline)] +fn pow5_factor(mut value: u32) -> u32 { + let mut count = 0u32; + loop { + debug_assert!(value != 0); + let q = value / 5; + let r = value % 5; + if r != 0 { + break; + } + value = q; + count += 1; + } + count +} + +// Returns true if value is divisible by 5^p. +#[cfg_attr(feature = "no-panic", inline)] +fn multiple_of_power_of_5(value: u32, p: u32) -> bool { + pow5_factor(value) >= p +} + +// Returns true if value is divisible by 2^p. +#[cfg_attr(feature = "no-panic", inline)] +fn multiple_of_power_of_2(value: u32, p: u32) -> bool { + // return __builtin_ctz(value) >= p; + (value & ((1u32 << p) - 1)) == 0 +} + +// It seems to be slightly faster to avoid uint128_t here, although the +// generated code for uint128_t looks slightly nicer. +#[cfg_attr(feature = "no-panic", inline)] +fn mul_shift(m: u32, factor: u64, shift: i32) -> u32 { + debug_assert!(shift > 32); + + // The casts here help MSVC to avoid calls to the __allmul library + // function. + let factor_lo = factor as u32; + let factor_hi = (factor >> 32) as u32; + let bits0 = m as u64 * factor_lo as u64; + let bits1 = m as u64 * factor_hi as u64; + + let sum = (bits0 >> 32) + bits1; + let shifted_sum = sum >> (shift - 32); + debug_assert!(shifted_sum <= u32::max_value() as u64); + shifted_sum as u32 +} + +#[cfg_attr(feature = "no-panic", inline)] +fn mul_pow5_inv_div_pow2(m: u32, q: u32, j: i32) -> u32 { + debug_assert!(q < FLOAT_POW5_INV_SPLIT.len() as u32); + unsafe { mul_shift(m, *FLOAT_POW5_INV_SPLIT.get_unchecked(q as usize), j) } +} + +#[cfg_attr(feature = "no-panic", inline)] +fn mul_pow5_div_pow2(m: u32, i: u32, j: i32) -> u32 { + debug_assert!(i < FLOAT_POW5_SPLIT.len() as u32); + unsafe { mul_shift(m, *FLOAT_POW5_SPLIT.get_unchecked(i as usize), j) } +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn decimal_length(v: u32) -> u32 { + // Function precondition: v is not a 10-digit number. + // (9 digits are sufficient for round-tripping.) + debug_assert!(v < 1000000000); + + if v >= 100000000 { + 9 + } else if v >= 10000000 { + 8 + } else if v >= 1000000 { + 7 + } else if v >= 100000 { + 6 + } else if v >= 10000 { + 5 + } else if v >= 1000 { + 4 + } else if v >= 100 { + 3 + } else if v >= 10 { + 2 + } else { + 1 + } +} + +// A floating decimal representing m * 10^e. +pub struct FloatingDecimal32 { + pub mantissa: u32, + pub exponent: i32, +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn f2d(ieee_mantissa: u32, ieee_exponent: u32) -> FloatingDecimal32 { + let bias = (1u32 << (FLOAT_EXPONENT_BITS - 1)) - 1; + + let (e2, m2) = if ieee_exponent == 0 { + ( + // We subtract 2 so that the bounds computation has 2 additional bits. + 1 - bias as i32 - FLOAT_MANTISSA_BITS as i32 - 2, + ieee_mantissa, + ) + } else { + ( + ieee_exponent as i32 - bias as i32 - FLOAT_MANTISSA_BITS as i32 - 2, + (1u32 << FLOAT_MANTISSA_BITS) | ieee_mantissa, + ) + }; + let even = (m2 & 1) == 0; + let accept_bounds = even; + + // Step 2: Determine the interval of legal decimal representations. + let mv = 4 * m2; + let mp = 4 * m2 + 2; + // Implicit bool -> int conversion. True is 1, false is 0. + let mm_shift = (ieee_mantissa != 0 || ieee_exponent <= 1) as u32; + let mm = 4 * m2 - 1 - mm_shift; + + // Step 3: Convert to a decimal power base using 64-bit arithmetic. + let mut vr: u32; + let mut vp: u32; + let mut vm: u32; + let e10: i32; + let mut vm_is_trailing_zeros = false; + let mut vr_is_trailing_zeros = false; + let mut last_removed_digit = 0u8; + if e2 >= 0 { + let q = log10_pow2(e2) as u32; + e10 = q as i32; + let k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32) as i32 - 1; + let i = -e2 + q as i32 + k; + vr = mul_pow5_inv_div_pow2(mv, q, i); + vp = mul_pow5_inv_div_pow2(mp, q, i); + vm = mul_pow5_inv_div_pow2(mm, q, i); + if q != 0 && (vp - 1) / 10 <= vm / 10 { + // We need to know one removed digit even if we are not going to loop below. We could use + // q = X - 1 above, except that would require 33 bits for the result, and we've found that + // 32-bit arithmetic is faster even on 64-bit machines. + let l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q as i32 - 1) as i32 - 1; + last_removed_digit = + (mul_pow5_inv_div_pow2(mv, q - 1, -e2 + q as i32 - 1 + l) % 10) as u8; + } + if q <= 9 { + // The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 seems to be safe as well. + // Only one of mp, mv, and mm can be a multiple of 5, if any. + if mv % 5 == 0 { + vr_is_trailing_zeros = multiple_of_power_of_5(mv, q); + } else if accept_bounds { + vm_is_trailing_zeros = multiple_of_power_of_5(mm, q); + } else { + vp -= multiple_of_power_of_5(mp, q) as u32; + } + } + } else { + let q = log10_pow5(-e2) as u32; + e10 = q as i32 + e2; + let i = -e2 - q as i32; + let k = pow5bits(i) as i32 - FLOAT_POW5_BITCOUNT; + let mut j = q as i32 - k; + vr = mul_pow5_div_pow2(mv, i as u32, j); + vp = mul_pow5_div_pow2(mp, i as u32, j); + vm = mul_pow5_div_pow2(mm, i as u32, j); + if q != 0 && (vp - 1) / 10 <= vm / 10 { + j = q as i32 - 1 - (pow5bits(i + 1) as i32 - FLOAT_POW5_BITCOUNT); + last_removed_digit = (mul_pow5_div_pow2(mv, (i + 1) as u32, j) % 10) as u8; + } + if q <= 1 { + // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits. + // mv = 4 * m2, so it always has at least two trailing 0 bits. + vr_is_trailing_zeros = true; + if accept_bounds { + // mm = mv - 1 - mm_shift, so it has 1 trailing 0 bit iff mm_shift == 1. + vm_is_trailing_zeros = mm_shift == 1; + } else { + // mp = mv + 2, so it always has at least one trailing 0 bit. + vp -= 1; + } + } else if q < 31 { + // TODO(ulfjack): Use a tighter bound here. + vr_is_trailing_zeros = multiple_of_power_of_2(mv, q - 1); + } + } + + // Step 4: Find the shortest decimal representation in the interval of legal representations. + let mut removed = 0u32; + let output = if vm_is_trailing_zeros || vr_is_trailing_zeros { + // General case, which happens rarely (~4.0%). + while vp / 10 > vm / 10 { + vm_is_trailing_zeros &= vm - (vm / 10) * 10 == 0; + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + if vm_is_trailing_zeros { + while vm % 10 == 0 { + vr_is_trailing_zeros &= last_removed_digit == 0; + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + } + if vr_is_trailing_zeros && last_removed_digit == 5 && vr % 2 == 0 { + // Round even if the exact number is .....50..0. + last_removed_digit = 4; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + ((vr == vm && (!accept_bounds || !vm_is_trailing_zeros)) || last_removed_digit >= 5) + as u32 + } else { + // Specialized for the common case (~96.0%). Percentages below are relative to this. + // Loop iterations below (approximately): + // 0: 13.6%, 1: 70.7%, 2: 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% + while vp / 10 > vm / 10 { + last_removed_digit = (vr % 10) as u8; + vr /= 10; + vp /= 10; + vm /= 10; + removed += 1; + } + // We need to take vr + 1 if vr is outside bounds or we need to round up. + vr + (vr == vm || last_removed_digit >= 5) as u32 + }; + let exp = e10 + removed as i32; + + FloatingDecimal32 { + exponent: exp, + mantissa: output, + } +} + +#[cfg_attr(feature = "no-panic", inline)] +unsafe fn to_chars(v: FloatingDecimal32, sign: bool, result: *mut u8) -> usize { + // Step 5: Print the decimal representation. + let mut index = 0isize; + if sign { + *result.offset(index) = b'-'; + index += 1; + } + + let mut output = v.mantissa; + let olength = decimal_length(output); + + // Print the decimal digits. + // The following code is equivalent to: + // for (uint32_t i = 0; i < olength - 1; ++i) { + // const uint32_t c = output % 10; output /= 10; + // result[index + olength - i] = (char) ('0' + c); + // } + // result[index] = '0' + output % 10; + let mut i = 0isize; + while output >= 10000 { + let c = output - 10000 * (output / 10000); + output /= 10000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c0 as usize), + result.offset(index + olength as isize - i - 1), + 2, + ); + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c1 as usize), + result.offset(index + olength as isize - i - 3), + 2, + ); + i += 4; + } + if output >= 100 { + let c = (output % 100) << 1; + output /= 100; + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked(c as usize), + result.offset(index + olength as isize - i - 1), + 2, + ); + i += 2; + } + if output >= 10 { + let c = output << 1; + // We can't use memcpy here: the decimal dot goes between these two digits. + *result.offset(index + olength as isize - i) = *DIGIT_TABLE.get_unchecked(c as usize + 1); + *result.offset(index) = *DIGIT_TABLE.get_unchecked(c as usize); + } else { + *result.offset(index) = b'0' + output as u8; + } + + // Print decimal point if needed. + if olength > 1 { + *result.offset(index + 1) = b'.'; + index += olength as isize + 1; + } else { + index += 1; + } + + // Print the exponent. + *result.offset(index) = b'E'; + index += 1; + let mut exp = v.exponent + olength as i32 - 1; + if exp < 0 { + *result.offset(index) = b'-'; + index += 1; + exp = -exp; + } + + if exp >= 10 { + ptr::copy_nonoverlapping( + DIGIT_TABLE.get_unchecked((2 * exp) as usize), + result.offset(index), + 2, + ); + index += 2; + } else { + *result.offset(index) = b'0' + exp as u8; + index += 1; + } + + debug_assert!(index <= 15); + index as usize +} + +/// Print f32 to the given buffer and return number of bytes written. +/// +/// At most 15 bytes will be written. +/// +/// ## Special cases +/// +/// This function represents any NaN as `NaN`, positive infinity as `Infinity`, +/// and negative infinity as `-Infinity`. +/// +/// ## Safety +/// +/// The `result` pointer argument must point to sufficiently many writable bytes +/// to hold Ryū's representation of `f`. +/// +/// ## Example +/// +/// ```rust +/// let f = 1.234f32; +/// +/// unsafe { +/// let mut buffer: [u8; 15] = std::mem::uninitialized(); +/// let n = ryu::raw::f2s_buffered_n(f, &mut buffer[0]); +/// let s = std::str::from_utf8_unchecked(&buffer[..n]); +/// assert_eq!(s, "1.234E0"); +/// } +/// ``` +#[cfg_attr(must_use_return, must_use)] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn f2s_buffered_n(f: f32, result: *mut u8) -> usize { + // Step 1: Decode the floating-point number, and unify normalized and subnormal cases. + let bits = mem::transmute::(f); + + // Decode bits into sign, mantissa, and exponent. + let ieee_sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1); + let ieee_exponent = + ((bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1)) as u32; + + // Case distinction; exit early for the easy cases. + if ieee_exponent == ((1u32 << FLOAT_EXPONENT_BITS) - 1) + || (ieee_exponent == 0 && ieee_mantissa == 0) + { + return copy_special_str(result, ieee_sign, ieee_exponent != 0, ieee_mantissa != 0); + } + + let v = f2d(ieee_mantissa, ieee_exponent); + to_chars(v, ieee_sign, result) +} diff --git a/third_party/rust/ryu/src/lib.rs b/third_party/rust/ryu/src/lib.rs new file mode 100644 index 000000000000..ae64f026c2df --- /dev/null +++ b/third_party/rust/ryu/src/lib.rs @@ -0,0 +1,68 @@ +//! Pure Rust implementation of Ryū, an algorithm to quickly convert floating +//! point numbers to decimal strings. +//! +//! The PLDI'18 paper [*Ryū: fast float-to-string conversion*][paper] by Ulf +//! Adams includes a complete correctness proof of the algorithm. The paper is +//! available under the creative commons CC-BY-SA license. +//! +//! This Rust implementation is a line-by-line port of Ulf Adams' implementation +//! in C, [https://github.com/ulfjack/ryu][upstream]. The [`ryu::raw`][raw] +//! module exposes exactly the API and formatting of the C implementation as +//! unsafe pure Rust functions. There is additionally a safe API as demonstrated +//! in the example code below. The safe API uses the same underlying Ryū +//! algorithm but diverges from the formatting of the C implementation to +//! produce more human-readable output, for example `0.3` rather than `3E-1`. +//! +//! [paper]: https://dl.acm.org/citation.cfm?id=3192369 +//! [upstream]: https://github.com/ulfjack/ryu +//! [raw]: raw/index.html +//! +//! # Examples +//! +//! ```rust +//! extern crate ryu; +//! +//! fn main() { +//! let mut buffer = ryu::Buffer::new(); +//! let printed = buffer.format(1.234); +//! assert_eq!(printed, "1.234"); +//! } +//! ``` + +#![no_std] +#![doc(html_root_url = "https://docs.rs/ryu/0.2.4")] +#![cfg_attr(feature = "no-panic", feature(use_extern_macros))] +#![cfg_attr( + feature = "cargo-clippy", + allow( + cast_lossless, + cyclomatic_complexity, + many_single_char_names, + needless_pass_by_value, + unreadable_literal, + ) +)] + +#[cfg(feature = "no-panic")] +extern crate no_panic; + +mod buffer; +mod common; +mod d2s; +#[cfg(not(feature = "small"))] +mod d2s_full_table; +#[cfg(feature = "small")] +mod d2s_small_table; +mod digit_table; +mod f2s; +#[cfg(not(integer128))] +mod mulshift128; +mod pretty; + +pub use buffer::{Buffer, Float}; + +/// Unsafe functions that exactly mirror the API of the C implementation of Ryū. +pub mod raw { + pub use d2s::d2s_buffered_n; + pub use f2s::f2s_buffered_n; +} diff --git a/third_party/rust/ryu/src/mulshift128.rs b/third_party/rust/ryu/src/mulshift128.rs new file mode 100644 index 000000000000..2112245ab012 --- /dev/null +++ b/third_party/rust/ryu/src/mulshift128.rs @@ -0,0 +1,57 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +// Returns (lo, hi). +#[cfg_attr(feature = "no-panic", inline)] +pub fn umul128(a: u64, b: u64) -> (u64, u64) { + let a_lo = a as u32; + let a_hi = (a >> 32) as u32; + let b_lo = b as u32; + let b_hi = (b >> 32) as u32; + + let b00 = a_lo as u64 * b_lo as u64; + let b01 = a_lo as u64 * b_hi as u64; + let b10 = a_hi as u64 * b_lo as u64; + let b11 = a_hi as u64 * b_hi as u64; + + let b00_lo = b00 as u32; + let b00_hi = (b00 >> 32) as u32; + + let mid1 = b10 + b00_hi as u64; + let mid1_lo = mid1 as u32; + let mid1_hi = (mid1 >> 32) as u32; + + let mid2 = b01 + mid1_lo as u64; + let mid2_lo = mid2 as u32; + let mid2_hi = (mid2 >> 32) as u32; + + let p_hi = b11 + mid1_hi as u64 + mid2_hi as u64; + let p_lo = ((mid2_lo as u64) << 32) + b00_lo as u64; + + (p_lo, p_hi) +} + +#[cfg_attr(feature = "no-panic", inline)] +pub fn shiftright128(lo: u64, hi: u64, dist: u32) -> u64 { + // We don't need to handle the case dist >= 64 here (see above). + debug_assert!(dist > 0); + debug_assert!(dist < 64); + (hi << (64 - dist)) | (lo >> dist) +} diff --git a/third_party/rust/ryu/src/pretty/exponent.rs b/third_party/rust/ryu/src/pretty/exponent.rs new file mode 100644 index 000000000000..f10643f22df6 --- /dev/null +++ b/third_party/rust/ryu/src/pretty/exponent.rs @@ -0,0 +1,49 @@ +use core::ptr; + +use digit_table::*; + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_exponent3(mut k: isize, mut result: *mut u8) -> usize { + let sign = k < 0; + if sign { + *result = b'-'; + result = result.offset(1); + k = -k; + } + + debug_assert!(k < 1000); + if k >= 100 { + *result = b'0' + (k / 100) as u8; + k %= 100; + let d = DIGIT_TABLE.get_unchecked(k as usize * 2); + ptr::copy_nonoverlapping(d, result.offset(1), 2); + sign as usize + 3 + } else if k >= 10 { + let d = DIGIT_TABLE.get_unchecked(k as usize * 2); + ptr::copy_nonoverlapping(d, result, 2); + sign as usize + 2 + } else { + *result = b'0' + k as u8; + sign as usize + 1 + } +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_exponent2(mut k: isize, mut result: *mut u8) -> usize { + let sign = k < 0; + if sign { + *result = b'-'; + result = result.offset(1); + k = -k; + } + + debug_assert!(k < 100); + if k >= 10 { + let d = DIGIT_TABLE.get_unchecked(k as usize * 2); + ptr::copy_nonoverlapping(d, result, 2); + sign as usize + 2 + } else { + *result = b'0' + k as u8; + sign as usize + 1 + } +} diff --git a/third_party/rust/ryu/src/pretty/mantissa.rs b/third_party/rust/ryu/src/pretty/mantissa.rs new file mode 100644 index 000000000000..428023233d87 --- /dev/null +++ b/third_party/rust/ryu/src/pretty/mantissa.rs @@ -0,0 +1,51 @@ +use core::ptr; + +use digit_table::*; + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_mantissa_long(mut output: u64, mut result: *mut u8) { + if (output >> 32) != 0 { + // One expensive 64-bit division. + let mut output2 = (output - 100_000_000 * (output / 100_000_000)) as u32; + output /= 100_000_000; + + let c = output2 % 10_000; + output2 /= 10_000; + let d = output2 % 10_000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + let d0 = (d % 100) << 1; + let d1 = (d / 100) << 1; + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c0 as usize), result.offset(-2), 2); + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c1 as usize), result.offset(-4), 2); + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(d0 as usize), result.offset(-6), 2); + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(d1 as usize), result.offset(-8), 2); + result = result.offset(-8); + } + write_mantissa(output as u32, result); +} + +#[cfg_attr(feature = "no-panic", inline)] +pub unsafe fn write_mantissa(mut output: u32, mut result: *mut u8) { + while output >= 10_000 { + let c = (output - 10_000 * (output / 10_000)) as u32; + output /= 10_000; + let c0 = (c % 100) << 1; + let c1 = (c / 100) << 1; + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c0 as usize), result.offset(-2), 2); + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c1 as usize), result.offset(-4), 2); + result = result.offset(-4); + } + if output >= 100 { + let c = ((output % 100) << 1) as u32; + output /= 100; + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c as usize), result.offset(-2), 2); + result = result.offset(-2); + } + if output >= 10 { + let c = (output << 1) as u32; + ptr::copy_nonoverlapping(DIGIT_TABLE.get_unchecked(c as usize), result.offset(-2), 2); + } else { + *result.offset(-1) = b'0' + output as u8; + } +} diff --git a/third_party/rust/ryu/src/pretty/mod.rs b/third_party/rust/ryu/src/pretty/mod.rs new file mode 100644 index 000000000000..413f1f45d96c --- /dev/null +++ b/third_party/rust/ryu/src/pretty/mod.rs @@ -0,0 +1,154 @@ +mod exponent; +mod mantissa; + +use core::{mem, ptr}; + +use self::exponent::*; +use self::mantissa::*; +use d2s; +use d2s::*; +use f2s; +use f2s::*; + +#[cfg(feature = "no-panic")] +use no_panic::no_panic; + +#[cfg_attr(must_use_return, must_use)] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn d2s_buffered_n(f: f64, result: *mut u8) -> usize { + let bits = mem::transmute::(f); + let sign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u64 << DOUBLE_MANTISSA_BITS) - 1); + let ieee_exponent = + (bits >> DOUBLE_MANTISSA_BITS) as u32 & ((1u32 << DOUBLE_EXPONENT_BITS) - 1); + + let mut index = 0isize; + if sign { + *result = b'-'; + index += 1; + } + + if ieee_exponent == 0 && ieee_mantissa == 0 { + ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3); + return sign as usize + 3; + } + + let v = d2d(ieee_mantissa, ieee_exponent); + + let length = d2s::decimal_length(v.mantissa) as isize; + let k = v.exponent as isize; + let kk = length + k; // 10^(kk-1) <= v < 10^kk + debug_assert!(k >= -324); + + if 0 <= k && kk <= 16 { + // 1234e7 -> 12340000000.0 + write_mantissa_long(v.mantissa, result.offset(index + length)); + for i in length..kk { + *result.offset(index + i) = b'0'; + } + *result.offset(index + kk) = b'.'; + *result.offset(index + kk + 1) = b'0'; + index as usize + kk as usize + 2 + } else if 0 < kk && kk <= 16 { + // 1234e-2 -> 12.34 + write_mantissa_long(v.mantissa, result.offset(index + length + 1)); + ptr::copy(result.offset(index + 1), result.offset(index), kk as usize); + *result.offset(index + kk) = b'.'; + index as usize + length as usize + 1 + } else if -5 < kk && kk <= 0 { + // 1234e-6 -> 0.001234 + *result.offset(index) = b'0'; + *result.offset(index + 1) = b'.'; + let offset = 2 - kk; + for i in 2..offset { + *result.offset(index + i) = b'0'; + } + write_mantissa_long(v.mantissa, result.offset(index + length + offset)); + index as usize + length as usize + offset as usize + } else if length == 1 { + // 1e30 + *result.offset(index) = b'0' + v.mantissa as u8; + *result.offset(index + 1) = b'e'; + index as usize + 2 + write_exponent3(kk - 1, result.offset(index + 2)) + } else { + // 1234e30 -> 1.234e33 + write_mantissa_long(v.mantissa, result.offset(index + length + 1)); + *result.offset(index) = *result.offset(index + 1); + *result.offset(index + 1) = b'.'; + *result.offset(index + length + 1) = b'e'; + index as usize + + length as usize + + 2 + + write_exponent3(kk - 1, result.offset(index + length + 2)) + } +} + +#[cfg_attr(must_use_return, must_use)] +#[cfg_attr(feature = "no-panic", no_panic)] +pub unsafe fn f2s_buffered_n(f: f32, result: *mut u8) -> usize { + let bits = mem::transmute::(f); + let sign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + let ieee_mantissa = bits & ((1u32 << FLOAT_MANTISSA_BITS) - 1); + let ieee_exponent = + ((bits >> FLOAT_MANTISSA_BITS) & ((1u32 << FLOAT_EXPONENT_BITS) - 1)) as u32; + + let mut index = 0isize; + if sign { + *result = b'-'; + index += 1; + } + + if ieee_exponent == 0 && ieee_mantissa == 0 { + ptr::copy_nonoverlapping(b"0.0".as_ptr(), result.offset(index), 3); + return sign as usize + 3; + } + + let v = f2d(ieee_mantissa, ieee_exponent); + + let length = f2s::decimal_length(v.mantissa) as isize; + let k = v.exponent as isize; + let kk = length + k; // 10^(kk-1) <= v < 10^kk + debug_assert!(k >= -45); + + if 0 <= k && kk <= 13 { + // 1234e7 -> 12340000000.0 + write_mantissa(v.mantissa, result.offset(index + length)); + for i in length..kk { + *result.offset(index + i) = b'0'; + } + *result.offset(index + kk) = b'.'; + *result.offset(index + kk + 1) = b'0'; + index as usize + kk as usize + 2 + } else if 0 < kk && kk <= 13 { + // 1234e-2 -> 12.34 + write_mantissa(v.mantissa, result.offset(index + length + 1)); + ptr::copy(result.offset(index + 1), result.offset(index), kk as usize); + *result.offset(index + kk) = b'.'; + index as usize + length as usize + 1 + } else if -6 < kk && kk <= 0 { + // 1234e-6 -> 0.001234 + *result.offset(index) = b'0'; + *result.offset(index + 1) = b'.'; + let offset = 2 - kk; + for i in 2..offset { + *result.offset(index + i) = b'0'; + } + write_mantissa(v.mantissa, result.offset(index + length + offset)); + index as usize + length as usize + offset as usize + } else if length == 1 { + // 1e30 + *result.offset(index) = b'0' + v.mantissa as u8; + *result.offset(index + 1) = b'e'; + index as usize + 2 + write_exponent2(kk - 1, result.offset(index + 2)) + } else { + // 1234e30 -> 1.234e33 + write_mantissa(v.mantissa, result.offset(index + length + 1)); + *result.offset(index) = *result.offset(index + 1); + *result.offset(index + 1) = b'.'; + *result.offset(index + length + 1) = b'e'; + index as usize + + length as usize + + 2 + + write_exponent2(kk - 1, result.offset(index + length + 2)) + } +} diff --git a/third_party/rust/ryu/tests/d2s_table_test.rs b/third_party/rust/ryu/tests/d2s_table_test.rs new file mode 100644 index 000000000000..64682e0a33ae --- /dev/null +++ b/third_party/rust/ryu/tests/d2s_table_test.rs @@ -0,0 +1,52 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +#![allow(dead_code)] + +extern crate core; + +#[path = "../src/common.rs"] +mod common; + +#[path = "../src/d2s_full_table.rs"] +mod d2s_full_table; + +#[path = "../src/d2s_small_table.rs"] +mod d2s_small_table; + +#[path = "../src/mulshift128.rs"] +mod mulshift128; + +use d2s_full_table::*; +use d2s_small_table::*; + +#[test] +fn test_compute_pow5() { + for (i, entry) in DOUBLE_POW5_SPLIT.iter().enumerate() { + assert_eq!(*entry, unsafe { compute_pow5(i as u32) }, "entry {}", i); + } +} + +#[test] +fn test_compute_inv_pow5() { + for (i, entry) in DOUBLE_POW5_INV_SPLIT.iter().enumerate() { + assert_eq!(*entry, unsafe { compute_inv_pow5(i as u32) }, "entry {}", i); + } +} diff --git a/third_party/rust/ryu/tests/d2s_test.rs b/third_party/rust/ryu/tests/d2s_test.rs new file mode 100644 index 000000000000..4586c2a4f399 --- /dev/null +++ b/third_party/rust/ryu/tests/d2s_test.rs @@ -0,0 +1,154 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +extern crate rand; +extern crate ryu; + +#[macro_use] +mod macros; + +use std::{f64, str}; + +fn print(f: f64) -> String { + let mut bytes = [0u8; 24]; + let n = unsafe { ryu::raw::d2s_buffered_n(f, &mut bytes[0]) }; + let s = str::from_utf8(&bytes[..n]).unwrap(); + s.to_owned() +} + +fn pretty(f: f64) -> String { + ryu::Buffer::new().format(f).to_owned() +} + +#[test] +fn test_ryu() { + check!(3E-1, 0.3); + check!(1.234E15, 1234000000000000.0); + check!(1.234E16, 1.234e16); + check!(2.71828E0, 2.71828); + check!(1.1E128, 1.1e128); + check!(1.1E-64, 1.1e-64); + check!(2.718281828459045E0, 2.718281828459045); + check!(5E-324, 5e-324); + check!(1.7976931348623157E308, 1.7976931348623157e308); +} + +#[test] +fn test_random() { + let mut bytes = [0u8; 24]; + let mut buffer = ryu::Buffer::new(); + for _ in 0..1000000 { + let f = rand::random(); + let n = unsafe { ryu::raw::d2s_buffered_n(f, &mut bytes[0]) }; + assert_eq!(f, str::from_utf8(&bytes[..n]).unwrap().parse().unwrap()); + assert_eq!(f, buffer.format(f).parse().unwrap()); + } +} + +#[test] +fn test_non_finite() { + for i in 0u64..1 << 23 { + let f = f64::from_bits((((1 << 11) - 1) << 52) + (i << 29)); + assert!(!f.is_finite(), "f={}", f); + ryu::Buffer::new().format(f); + } +} + +#[test] +fn test_basic() { + check!(0E0, 0.0); + check!(-0E0, -0.0); + check!(1E0, 1.0); + check!(-1E0, -1.0); + assert_eq!(print(f64::NAN), "NaN"); + assert_eq!(print(f64::INFINITY), "Infinity"); + assert_eq!(print(f64::NEG_INFINITY), "-Infinity"); +} + +#[test] +fn test_switch_to_subnormal() { + check!(2.2250738585072014E-308, 2.2250738585072014e-308); +} + +#[test] +fn test_min_and_max() { + assert_eq!(f64::from_bits(0x7fefffffffffffff), 1.7976931348623157e308); + check!(1.7976931348623157E308, 1.7976931348623157e308); + assert_eq!(f64::from_bits(1), 5e-324); + check!(5E-324, 5e-324); +} + +#[test] +fn test_lots_of_trailing_zeros() { + check!(2.9802322387695312E-8, 2.9802322387695312e-8); +} + +#[test] +fn test_regression() { + check!(-2.109808898695963E16, -2.109808898695963e16); + check!(4.940656E-318, 4.940656e-318); + check!(1.18575755E-316, 1.18575755e-316); + check!(2.989102097996E-312, 2.989102097996e-312); + check!(9.0608011534336E15, 9060801153433600.0); + check!(4.708356024711512E18, 4.708356024711512e18); + check!(9.409340012568248E18, 9.409340012568248e18); + check!(1.2345678E0, 1.2345678); +} + +#[test] +fn test_looks_like_pow5() { + // These numbers have a mantissa that is a multiple of the largest power of + // 5 that fits, and an exponent that causes the computation for q to result + // in 22, which is a corner case for Ryu. + assert_eq!(f64::from_bits(0x4830F0CF064DD592), 5.764607523034235e39); + check!(5.764607523034235E39, 5.764607523034235e39); + assert_eq!(f64::from_bits(0x4840F0CF064DD592), 1.152921504606847e40); + check!(1.152921504606847E40, 1.152921504606847e40); + assert_eq!(f64::from_bits(0x4850F0CF064DD592), 2.305843009213694e40); + check!(2.305843009213694E40, 2.305843009213694e40); +} + +#[test] +fn test_output_length() { + check!(1E0, 1.0); // already tested in Basic + check!(1.2E0, 1.2); + check!(1.23E0, 1.23); + check!(1.234E0, 1.234); + check!(1.2345E0, 1.2345); + check!(1.23456E0, 1.23456); + check!(1.234567E0, 1.234567); + check!(1.2345678E0, 1.2345678); // already tested in Regression + check!(1.23456789E0, 1.23456789); + check!(1.234567895E0, 1.234567895); // 1.234567890 would be trimmed + check!(1.2345678901E0, 1.2345678901); + check!(1.23456789012E0, 1.23456789012); + check!(1.234567890123E0, 1.234567890123); + check!(1.2345678901234E0, 1.2345678901234); + check!(1.23456789012345E0, 1.23456789012345); + check!(1.234567890123456E0, 1.234567890123456); + check!(1.2345678901234567E0, 1.2345678901234567); + + // Test 32-bit chunking + check!(4.294967294E0, 4.294967294); // 2^32 - 2 + check!(4.294967295E0, 4.294967295); // 2^32 - 1 + check!(4.294967296E0, 4.294967296); // 2^32 + check!(4.294967297E0, 4.294967297); // 2^32 + 1 + check!(4.294967298E0, 4.294967298); // 2^32 + 2 +} diff --git a/third_party/rust/ryu/tests/exhaustive.rs b/third_party/rust/ryu/tests/exhaustive.rs new file mode 100644 index 000000000000..80e476e264ef --- /dev/null +++ b/third_party/rust/ryu/tests/exhaustive.rs @@ -0,0 +1,55 @@ +#![cfg(exhaustive)] + +extern crate num_cpus; +extern crate ryu; + +use std::str; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; +use std::thread; + +#[test] +fn test_exhaustive() { + const BATCH_SIZE: u32 = 1_000_000; + let counter = Arc::new(AtomicUsize::new(0)); + let finished = Arc::new(AtomicUsize::new(0)); + + let mut workers = Vec::new(); + for _ in 0..num_cpus::get() { + let counter = counter.clone(); + let finished = finished.clone(); + workers.push(thread::spawn(move || loop { + let batch = counter.fetch_add(1, Ordering::SeqCst) as u32; + if batch > u32::max_value() / BATCH_SIZE { + return; + } + + let min = batch * BATCH_SIZE; + let max = if batch == u32::max_value() / BATCH_SIZE { + u32::max_value() + } else { + min + BATCH_SIZE - 1 + }; + + let mut bytes = [0u8; 24]; + let mut buffer = ryu::Buffer::new(); + for u in min..=max { + let f = f32::from_bits(u); + if !f.is_finite() { + continue; + } + let n = unsafe { ryu::raw::f2s_buffered_n(f, &mut bytes[0]) }; + assert_eq!(Ok(Ok(f)), str::from_utf8(&bytes[..n]).map(str::parse)); + assert_eq!(Ok(f), buffer.format(f).parse()); + } + + let increment = (max - min + 1) as usize; + let update = finished.fetch_add(increment, Ordering::SeqCst); + println!("{}", update + increment); + })); + } + + for w in workers { + w.join().unwrap(); + } +} diff --git a/third_party/rust/ryu/tests/f2s_test.rs b/third_party/rust/ryu/tests/f2s_test.rs new file mode 100644 index 000000000000..24cb814e2a49 --- /dev/null +++ b/third_party/rust/ryu/tests/f2s_test.rs @@ -0,0 +1,183 @@ +// Translated from C to Rust. The original C code can be found at +// https://github.com/ulfjack/ryu and carries the following license: +// +// Copyright 2018 Ulf Adams +// +// The contents of this file may be used under the terms of the Apache License, +// Version 2.0. +// +// (See accompanying file LICENSE-Apache or copy at +// http://www.apache.org/licenses/LICENSE-2.0) +// +// Alternatively, the contents of this file may be used under the terms of +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE-Boost or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// Unless required by applicable law or agreed to in writing, this software +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. + +extern crate rand; +extern crate ryu; + +#[macro_use] +mod macros; + +use std::{f32, str}; + +fn print(f: f32) -> String { + let mut bytes = [0u8; 24]; + let n = unsafe { ryu::raw::f2s_buffered_n(f, &mut bytes[0]) }; + let s = str::from_utf8(&bytes[..n]).unwrap(); + s.to_owned() +} + +fn pretty(f: f32) -> String { + ryu::Buffer::new().format(f).to_owned() +} + +#[test] +fn test_ryu() { + check!(3E-1, 0.3); + check!(1.234E12, 1234000000000.0); + check!(1.234E13, 1.234e13); + check!(2.71828E0, 2.71828); + check!(1.1E32, 1.1e32); + check!(1.1E-32, 1.1e-32); + check!(2.7182817E0, 2.7182817); + check!(1E-45, 1e-45); + check!(3.4028235E38, 3.4028235e38); + check!(-1.234E-3, -0.001234); +} + +#[test] +fn test_random() { + let mut bytes = [0u8; 24]; + let mut buffer = ryu::Buffer::new(); + for _ in 0..1000000 { + let f = rand::random(); + let n = unsafe { ryu::raw::f2s_buffered_n(f, &mut bytes[0]) }; + assert_eq!(f, str::from_utf8(&bytes[..n]).unwrap().parse().unwrap()); + assert_eq!(f, buffer.format(f).parse().unwrap()); + } +} + +#[test] +fn test_non_finite() { + for i in 0u32..1 << 23 { + let f = f32::from_bits((((1 << 8) - 1) << 23) + i); + assert!(!f.is_finite(), "f={}", f); + ryu::Buffer::new().format(f); + } +} + +#[test] +fn test_basic() { + check!(0E0, 0.0); + check!(-0E0, -0.0); + check!(1E0, 1.0); + check!(-1E0, -1.0); + assert_eq!(print(f32::NAN), "NaN"); + assert_eq!(print(f32::INFINITY), "Infinity"); + assert_eq!(print(f32::NEG_INFINITY), "-Infinity"); +} + +#[test] +fn test_switch_to_subnormal() { + check!(1.1754944E-38, 1.1754944e-38); +} + +#[test] +fn test_min_and_max() { + assert_eq!(f32::from_bits(0x7f7fffff), 3.4028235e38); + check!(3.4028235E38, 3.4028235e38); + assert_eq!(f32::from_bits(1), 1e-45); + check!(1E-45, 1e-45); +} + +// Check that we return the exact boundary if it is the shortest +// representation, but only if the original floating point number is even. +#[test] +fn test_boundary_round_even() { + check!(3.355445E7, 33554450.0); + check!(9E9, 9000000000.0); + check!(3.436672E10, 34366720000.0); +} + +// If the exact value is exactly halfway between two shortest representations, +// then we round to even. It seems like this only makes a difference if the +// last two digits are ...2|5 or ...7|5, and we cut off the 5. +#[test] +fn test_exact_value_round_even() { + check!(3.0540412E5, 305404.12); + check!(8.0990312E3, 8099.0312); +} + +#[test] +fn test_lots_of_trailing_zeros() { + // Pattern for the first test: 00111001100000000000000000000000 + check!(2.4414062E-4, 0.00024414062); + check!(2.4414062E-3, 0.0024414062); + check!(4.3945312E-3, 0.0043945312); + check!(6.3476562E-3, 0.0063476562); +} + +#[test] +fn test_regression() { + check!(4.7223665E21, 4.7223665e21); + check!(8.388608E6, 8388608.0); + check!(1.6777216E7, 16777216.0); + check!(3.3554436E7, 33554436.0); + check!(6.7131496E7, 67131496.0); + check!(1.9310392E-38, 1.9310392e-38); + check!(-2.47E-43, -2.47e-43); + check!(1.993244E-38, 1.993244e-38); + check!(4.1039004E3, 4103.9004); + check!(5.3399997E9, 5339999700.0); + check!(6.0898E-39, 6.0898e-39); + check!(1.0310042E-3, 0.0010310042); + check!(2.882326E17, 2.882326e17); + check!(7.038531E-26, 7.038531e-26); + check!(9.223404E17, 9.223404e17); + check!(6.710887E7, 67108870.0); + check!(1E-44, 1e-44); + check!(2.816025E14, 2.816025e14); + check!(9.223372E18, 9.223372e18); + check!(1.5846086E29, 1.5846086e29); + check!(1.1811161E19, 1.1811161e19); + check!(5.368709E18, 5.368709e18); + check!(4.6143166E18, 4.6143166e18); + check!(7.812537E-3, 0.007812537); + check!(1E-45, 1e-45); + check!(1.18697725E20, 1.18697725e20); + check!(1.00014165E-36, 1.00014165e-36); + check!(2E2, 200.0); + check!(3.3554432E7, 33554432.0); +} + +#[test] +fn test_looks_like_pow5() { + // These numbers have a mantissa that is the largest power of 5 that fits, + // and an exponent that causes the computation for q to result in 10, which + // is a corner case for Ryu. + assert_eq!(f32::from_bits(0x5D1502F9), 6.7108864e17); + check!(6.7108864E17, 6.7108864e17); + assert_eq!(f32::from_bits(0x5D9502F9), 1.3421773e18); + check!(1.3421773E18, 1.3421773e18); + assert_eq!(f32::from_bits(0x5E1502F9), 2.6843546e18); + check!(2.6843546E18, 2.6843546e18); +} + +#[test] +fn test_output_length() { + check!(1E0, 1.0); // already tested in Basic + check!(1.2E0, 1.2); + check!(1.23E0, 1.23); + check!(1.234E0, 1.234); + check!(1.2345E0, 1.2345); + check!(1.23456E0, 1.23456); + check!(1.234567E0, 1.234567); + check!(1.2345678E0, 1.2345678); + check!(1.23456735E-36, 1.23456735e-36); +} diff --git a/third_party/rust/ryu/tests/macros/mod.rs b/third_party/rust/ryu/tests/macros/mod.rs new file mode 100644 index 000000000000..09cd218b9cff --- /dev/null +++ b/third_party/rust/ryu/tests/macros/mod.rs @@ -0,0 +1,12 @@ +macro_rules! check { + ($ryu:tt, $pretty:tt) => { + assert_eq!($ryu, $pretty); + assert_eq!(print($ryu), stringify!($ryu)); + assert_eq!(pretty($pretty), stringify!($pretty)); + }; + (-$ryu:tt, -$pretty:tt) => { + assert_eq!(-$ryu, -$pretty); + assert_eq!(print(-$ryu), concat!("-", stringify!($ryu))); + assert_eq!(pretty(-$pretty), concat!("-", stringify!($pretty))); + }; +} diff --git a/third_party/rust/serde_json/.cargo-checksum.json b/third_party/rust/serde_json/.cargo-checksum.json new file mode 100644 index 000000000000..a4b5b1ebcdeb --- /dev/null +++ b/third_party/rust/serde_json/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"0265066945da4da5957f3446cef6f2a52e81254be3a9c4e678cc2c1e1160118b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"c4d8690cd2aa2db200ecdf2f2113fc8e3f4ccc88f3dc96da22189f45136932d0","src/de.rs":"42d7aa8cf85baa1b3851180e32af883c11ca2889df6f4eb306670f360af46d3e","src/error.rs":"8ac6d4c861891c133b3359b2a14fccb8a6d463a4b2c13f0d658884c1972186ce","src/iter.rs":"b5c77c5482e45bed1e63bd36a0f991a08f732811546a163228be48303e7f1b4d","src/lib.rs":"698af0adc583d8b5a22f510bb33fbdb35552dd6e0775e038f7ed50f6680580d8","src/macros.rs":"0d9850832f53c8aca337395b2536f1cdaf2d2d2699adc09c9a2001544106a4fc","src/map.rs":"724205f934003c879fb3e48a84b21c54e273e968beec97b85617042911ca88d7","src/number.rs":"47bf5416ca4f8299e98f008bd1bcf7e7311f00d0ce282536a17310fa73788def","src/read.rs":"832bc530dd35ee24df59c1cf648cfbbffc4c2e72e86104b0e186582ae0de545a","src/ser.rs":"d2050d362c23e988141e6c5d08590152b3412ee3464e1a3026b83dda7de0c985","src/value/de.rs":"b25d9192f179f84c0ecb2226216ff663c39ebdde524179f7118718f3202243cf","src/value/from.rs":"13a6c7b0b327f23c2fd899c8390e8ddfd8907bfcfc362e80834b9ae7ddb698e9","src/value/index.rs":"b9a8cc6f37e2a079a5e4ab1bf25fa9ff076c514870e0756a0c88af3ffa0f51a8","src/value/mod.rs":"8d0ac56fcd12aee1c645afdfe0df62b10527cab21d16284fe9f0bd6768457002","src/value/partial_eq.rs":"5924e245408afc8075e2bb9dda479c938c6c8cdd3c18b54697aa2b33fffda57b","src/value/ser.rs":"4bbc3ad0f646464f1e9b9a2c2e48df799d02ef658eacadc35971b897cfe7cd02"},"package":"44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae"} \ No newline at end of file diff --git a/third_party/rust/serde_json/Cargo.toml b/third_party/rust/serde_json/Cargo.toml new file mode 100644 index 000000000000..4f04167a77a7 --- /dev/null +++ b/third_party/rust/serde_json/Cargo.toml @@ -0,0 +1,54 @@ +# 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 believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "serde_json" +version = "1.0.26" +authors = ["Erick Tryzelaar ", "David Tolnay "] +include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] +description = "A JSON serialization file format" +documentation = "http://docs.serde.rs/serde_json/" +readme = "README.md" +keywords = ["json", "serde", "serialization"] +categories = ["encoding"] +license = "MIT/Apache-2.0" +repository = "https://github.com/serde-rs/json" +[dependencies.indexmap] +version = "1.0" +optional = true + +[dependencies.itoa] +version = "0.4" + +[dependencies.ryu] +version = "0.2" + +[dependencies.serde] +version = "1.0.60" +[dev-dependencies.compiletest_rs] +version = "0.3" + +[dev-dependencies.serde_bytes] +version = "0.10" + +[dev-dependencies.serde_derive] +version = "1.0" + +[features] +arbitrary_precision = [] +default = [] +preserve_order = ["indexmap"] +[badges.appveyor] +repository = "serde-rs/json" + +[badges.travis-ci] +repository = "serde-rs/json" diff --git a/third_party/rust/rustc-serialize/LICENSE-APACHE b/third_party/rust/serde_json/LICENSE-APACHE similarity index 100% rename from third_party/rust/rustc-serialize/LICENSE-APACHE rename to third_party/rust/serde_json/LICENSE-APACHE diff --git a/third_party/rust/rustc-serialize/LICENSE-MIT b/third_party/rust/serde_json/LICENSE-MIT similarity index 100% rename from third_party/rust/rustc-serialize/LICENSE-MIT rename to third_party/rust/serde_json/LICENSE-MIT diff --git a/third_party/rust/serde_json/README.md b/third_party/rust/serde_json/README.md new file mode 100644 index 000000000000..6d445108d5b8 --- /dev/null +++ b/third_party/rust/serde_json/README.md @@ -0,0 +1,365 @@ +# Serde JSON   [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.15+]][rustc] + +[Build Status]: https://api.travis-ci.org/serde-rs/json.svg?branch=master +[travis]: https://travis-ci.org/serde-rs/json +[Latest Version]: https://img.shields.io/crates/v/serde_json.svg +[crates.io]: https://crates.io/crates/serde\_json +[Rustc Version 1.15+]: https://img.shields.io/badge/rustc-1.15+-lightgray.svg +[rustc]: https://blog.rust-lang.org/2017/02/02/Rust-1.15.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.serde.rs/serde_json/) +- [Serde API documentation](https://docs.serde.rs/serde/) +- [Detailed documentation about Serde](https://serde.rs/) +- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.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,ignore +{ + "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,ignore +enum Value { + Null, + Bool(bool), + Number(Number), + String(String), + Array(Vec), + Object(Map), +} +``` + +A string of JSON data can be parsed into a `serde_json::Value` by the +[`serde_json::from_str`][from_str] function. There is also +[`from_slice`][from_slice] for parsing from a byte slice &[u8] and +[`from_reader`][from_reader] for parsing from any `io::Read` like a File or +a TCP stream. + + + + + +```rust +extern crate serde_json; + +use serde_json::{Value, Error}; + +fn untyped_example() -> Result<(), Error> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#"{ + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into serde_json::Value. + let v: Value = serde_json::from_str(data)?; + + // Access parts of the data by indexing with square brackets. + println!("Please call {} at the number {}", v["name"], v["phones"][0]); + + Ok(()) +} +``` + +The result of square bracket indexing like `v["name"]` is a borrow of the data +at that index, so the type is `&Value`. A JSON map can be indexed with string +keys, while a JSON array can be indexed with integer keys. If the type of the +data is not right for the type with which it is being indexed, or if a map does +not contain the key being indexed, or if the index into a vector is out of +bounds, the returned element is `Value::Null`. + +When a `Value` is printed, it is printed as a JSON string. So in the code above, +the output looks like `Please call "John Doe" at the number "+44 1234567"`. The +quotation marks appear because `v["name"]` is a `&Value` containing a JSON +string and its JSON representation is `"John Doe"`. Printing as a plain string +without quotation marks involves converting from a JSON string to a Rust string +with [`as_str()`] or avoiding the use of `Value` as described in the following +section. + +[`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str + +The `Value` representation is sufficient for very basic tasks but can be tedious +to work with for anything more significant. Error handling is verbose to +implement correctly, for example imagine trying to detect the presence of +unrecognized fields in the input data. The compiler is powerless to help you +when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]` +in one of the dozens of places it is used in your code. + +## Parsing JSON as strongly typed data structures + +Serde provides a powerful way of mapping JSON data into Rust data structures +largely automatically. + + + + + +```rust +extern crate serde; +extern crate serde_json; + +#[macro_use] +extern crate serde_derive; + +use serde_json::Error; + +#[derive(Serialize, Deserialize)] +struct Person { + name: String, + age: u8, + phones: Vec, +} + +fn typed_example() -> Result<(), Error> { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#"{ + "name": "John Doe", + "age": 43, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + // Parse the string of data into 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` +and `HashMap`, as well as any structs or enums annotated with +`#[derive(Deserialize)]`. + +Once we have `p` of type `Person`, our IDE and the Rust compiler can help us +use it correctly like they do for any other Rust code. The IDE can +autocomplete field names to prevent typos, which was impossible in the +`serde_json::Value` representation. And the Rust compiler can check that +when we write `p.phones[0]`, then `p.phones` is guaranteed to be a +`Vec` so indexing into it makes sense and produces a `String`. + +## Constructing JSON values + +Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +objects with very natural JSON syntax. In order to use this macro, +`serde_json` needs to be imported with the `#[macro_use]` attribute. + + + + + +```rust +#[macro_use] +extern crate serde_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. + + + + + +```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` which is that the IDE and Rust compiler cannot help us if we get it +wrong. Serde JSON provides a better way of serializing strongly-typed data +structures into JSON text. + +## Creating JSON by serializing data structures + +A data structure can be converted to a JSON string by +[`serde_json::to_string`][to_string]. There is also +[`serde_json::to_vec`][to_vec] which serializes to a `Vec` and +[`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +such as a File or a TCP stream. + + + + + +```rust +extern crate serde; +extern crate serde_json; + +#[macro_use] +extern crate serde_derive; + +use serde_json::Error; + +#[derive(Serialize, Deserialize)] +struct Address { + street: String, + city: String, +} + +fn print_an_address() -> Result<(), Error> { + // 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` and +`HashMap`, 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 developers live in the #serde channel on +[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a +good resource with generally faster response time but less specific knowledge +about Serde. If IRC is not your thing, we are happy to respond to [GitHub +issues](https://github.com/serde-rs/json/issues/new) as well. + +## No-std support + +This crate currently requires the Rust standard library. For JSON support in +Serde without a standard library, please see the [`serde-json-core`] crate. + +[`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ + +## License + +Serde JSON is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in Serde JSON by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. + +[value]: https://docs.serde.rs/serde_json/value/enum.Value.html +[from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html +[from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html +[from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html +[to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html +[to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html +[to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html +[macro]: https://docs.serde.rs/serde_json/macro.json.html diff --git a/third_party/rust/serde_json/src/de.rs b/third_party/rust/serde_json/src/de.rs new file mode 100644 index 000000000000..f1c5c3cffe87 --- /dev/null +++ b/third_party/rust/serde_json/src/de.rs @@ -0,0 +1,2265 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Deserialize JSON data to a Rust data structure. + +use std::io; +use std::marker::PhantomData; +use std::result; +use std::str::FromStr; +use std::{i32, u64}; + +use serde::de::{self, Expected, Unexpected}; + +use super::error::{Error, ErrorCode, Result}; + +use read::{self, Reference}; + +pub use read::{IoRead, Read, SliceRead, StrRead}; + +use number::Number; +#[cfg(feature = "arbitrary_precision")] +use number::NumberDeserializer; + +////////////////////////////////////////////////////////////////////////////// + +/// A structure that deserializes JSON into Rust values. +pub struct Deserializer { + read: R, + str_buf: Vec, + remaining_depth: u8, +} + +impl<'de, R> Deserializer +where + R: read::Read<'de>, +{ + /// Create a JSON deserializer from one of the possible serde_json input + /// sources. + /// + /// Typically it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str + /// - Deserializer::from_bytes + /// - Deserializer::from_reader + pub fn new(read: R) -> Self { + Deserializer { + read: read, + str_buf: Vec::with_capacity(128), + remaining_depth: 128, + } + } +} + +impl Deserializer> +where + R: io::Read, +{ + /// Creates a JSON deserializer from an `io::Read`. + pub fn from_reader(reader: R) -> Self { + Deserializer::new(read::IoRead::new(reader)) + } +} + +impl<'a> Deserializer> { + /// Creates a JSON deserializer from a `&[u8]`. + pub fn from_slice(bytes: &'a [u8]) -> Self { + Deserializer::new(read::SliceRead::new(bytes)) + } +} + +impl<'a> Deserializer> { + /// Creates a JSON deserializer from a `&str`. + pub fn from_str(s: &'a str) -> Self { + Deserializer::new(read::StrRead::new(s)) + } +} + +macro_rules! overflow { + ($a:ident * 10 + $b:ident, $c:expr) => { + $a >= $c / 10 && ($a > $c / 10 || $b > $c % 10) + }; +} + +// Not public API. Should be pub(crate). +#[doc(hidden)] +pub enum ParserNumber { + F64(f64), + U64(u64), + I64(i64), + #[cfg(feature = "arbitrary_precision")] + String(String), +} + +impl ParserNumber { + fn visit<'de, V>(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self { + ParserNumber::F64(x) => visitor.visit_f64(x), + ParserNumber::U64(x) => visitor.visit_u64(x), + ParserNumber::I64(x) => visitor.visit_i64(x), + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(x) => visitor.visit_map(NumberDeserializer { number: x.into() }), + } + } + + fn invalid_type(self, exp: &Expected) -> Error { + match self { + ParserNumber::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp), + ParserNumber::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp), + ParserNumber::I64(x) => de::Error::invalid_type(Unexpected::Signed(x), exp), + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(_) => de::Error::invalid_type(Unexpected::Other("number"), exp), + } + } +} + +impl<'de, R: Read<'de>> Deserializer { + /// The `Deserializer::end` method should be called after a value has been fully deserialized. + /// This allows the `Deserializer` to validate that the input stream is at the end or that it + /// only has trailing whitespace. + pub fn end(&mut self) -> Result<()> { + match try!(self.parse_whitespace()) { + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Ok(()), + } + } + + /// Turn a JSON deserializer into an iterator over values of type T. + pub fn into_iter(self) -> StreamDeserializer<'de, R, T> + where + T: de::Deserialize<'de>, + { + // This cannot be an implementation of std::iter::IntoIterator because + // we need the caller to choose what T is. + let offset = self.read.byte_offset(); + StreamDeserializer { + de: self, + offset: offset, + output: PhantomData, + lifetime: PhantomData, + } + } + + fn peek(&mut self) -> Result> { + self.read.peek().map_err(Error::io) + } + + fn peek_or_null(&mut self) -> Result { + Ok(try!(self.peek()).unwrap_or(b'\x00')) + } + + fn eat_char(&mut self) { + self.read.discard(); + } + + fn next_char(&mut self) -> Result> { + self.read.next().map_err(Error::io) + } + + fn next_char_or_null(&mut self) -> Result { + Ok(try!(self.next_char()).unwrap_or(b'\x00')) + } + + /// Error caused by a byte from next_char(). + #[cold] + fn error(&self, reason: ErrorCode) -> Error { + let position = self.read.position(); + Error::syntax(reason, position.line, position.column) + } + + /// Error caused by a byte from peek(). + #[cold] + fn peek_error(&self, reason: ErrorCode) -> Error { + let position = self.read.peek_position(); + Error::syntax(reason, position.line, position.column) + } + + /// Returns the first non-whitespace byte without consuming it, or `None` if + /// EOF is encountered. + fn parse_whitespace(&mut self) -> Result> { + loop { + match try!(self.peek()) { + Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => { + self.eat_char(); + } + other => { + return Ok(other); + } + } + } + } + + #[cold] + fn peek_invalid_type(&mut self, exp: &Expected) -> Error { + let err = match self.peek_or_null().unwrap_or(b'\x00') { + b'n' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"ull") { + return err; + } + de::Error::invalid_type(Unexpected::Unit, exp) + } + b't' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"rue") { + return err; + } + de::Error::invalid_type(Unexpected::Bool(true), exp) + } + b'f' => { + self.eat_char(); + if let Err(err) = self.parse_ident(b"alse") { + return err; + } + de::Error::invalid_type(Unexpected::Bool(false), exp) + } + b'-' => { + self.eat_char(); + match self.parse_any_number(false) { + Ok(n) => n.invalid_type(exp), + Err(err) => return err, + } + } + b'0'...b'9' => match self.parse_any_number(true) { + Ok(n) => n.invalid_type(exp), + Err(err) => return err, + }, + b'"' => { + self.eat_char(); + self.str_buf.clear(); + match self.read.parse_str(&mut self.str_buf) { + Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp), + Err(err) => return err, + } + } + b'[' => de::Error::invalid_type(Unexpected::Seq, exp), + b'{' => de::Error::invalid_type(Unexpected::Map, exp), + _ => self.peek_error(ErrorCode::ExpectedSomeValue), + }; + + self.fix_position(err) + } + + fn deserialize_prim_number(&mut self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'-' => { + self.eat_char(); + try!(self.parse_integer(false)).visit(visitor) + } + b'0'...b'9' => try!(self.parse_integer(true)).visit(visitor), + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + serde_if_integer128! { + fn scan_integer128(&mut self, buf: &mut String) -> Result<()> { + match try!(self.next_char_or_null()) { + b'0' => { + buf.push('0'); + // There can be only one leading '0'. + match try!(self.peek_or_null()) { + b'0'...b'9' => { + Err(self.peek_error(ErrorCode::InvalidNumber)) + } + _ => Ok(()), + } + } + c @ b'1'...b'9' => { + buf.push(c as char); + while let c @ b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + } + Ok(()) + } + _ => { + Err(self.error(ErrorCode::InvalidNumber)) + } + } + } + } + + #[cold] + fn fix_position(&self, err: Error) -> Error { + err.fix_position(move |code| self.error(code)) + } + + fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { + for expected in ident { + match try!(self.next_char()) { + None => { + return Err(self.error(ErrorCode::EofWhileParsingValue)); + } + Some(next) => { + if next != *expected { + return Err(self.error(ErrorCode::ExpectedSomeIdent)); + } + } + } + } + + Ok(()) + } + + fn parse_integer(&mut self, positive: bool) -> Result { + match try!(self.next_char_or_null()) { + b'0' => { + // There can be only one leading '0'. + match try!(self.peek_or_null()) { + b'0'...b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), + _ => self.parse_number(positive, 0), + } + } + c @ b'1'...b'9' => { + let mut res = (c - b'0') as u64; + + loop { + match try!(self.peek_or_null()) { + c @ b'0'...b'9' => { + self.eat_char(); + let digit = (c - b'0') as u64; + + // We need to be careful with overflow. If we can, try to keep the + // number as a `u64` until we grow too large. At that point, switch to + // parsing the value as a `f64`. + if overflow!(res * 10 + digit, u64::max_value()) { + return Ok(ParserNumber::F64(try!( + self.parse_long_integer( + positive, + res, + 1, // res * 10^1 + ) + ))); + } + + res = res * 10 + digit; + } + _ => { + return self.parse_number(positive, res); + } + } + } + } + _ => Err(self.error(ErrorCode::InvalidNumber)), + } + } + + fn parse_long_integer( + &mut self, + positive: bool, + significand: u64, + mut exponent: i32, + ) -> Result { + loop { + match try!(self.peek_or_null()) { + b'0'...b'9' => { + self.eat_char(); + // This could overflow... if your integer is gigabytes long. + // Ignore that possibility. + exponent += 1; + } + b'.' => { + return self.parse_decimal(positive, significand, exponent); + } + b'e' | b'E' => { + return self.parse_exponent(positive, significand, exponent); + } + _ => { + return self.f64_from_parts(positive, significand, exponent); + } + } + } + } + + fn parse_number(&mut self, positive: bool, significand: u64) -> Result { + Ok(match try!(self.peek_or_null()) { + b'.' => ParserNumber::F64(try!(self.parse_decimal(positive, significand, 0))), + b'e' | b'E' => ParserNumber::F64(try!(self.parse_exponent(positive, significand, 0))), + _ => { + if positive { + ParserNumber::U64(significand) + } else { + let neg = (significand as i64).wrapping_neg(); + + // Convert into a float if we underflow. + if neg > 0 { + ParserNumber::F64(-(significand as f64)) + } else { + ParserNumber::I64(neg) + } + } + } + }) + } + + fn parse_decimal( + &mut self, + positive: bool, + mut significand: u64, + mut exponent: i32, + ) -> Result { + self.eat_char(); + + let mut at_least_one_digit = false; + while let c @ b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + let digit = (c - b'0') as u64; + at_least_one_digit = true; + + if overflow!(significand * 10 + digit, u64::max_value()) { + // The next multiply/add would overflow, so just ignore all + // further digits. + while let b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + } + break; + } + + significand = significand * 10 + digit; + exponent -= 1; + } + + if !at_least_one_digit { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + + match try!(self.peek_or_null()) { + b'e' | b'E' => self.parse_exponent(positive, significand, exponent), + _ => self.f64_from_parts(positive, significand, exponent), + } + } + + fn parse_exponent( + &mut self, + positive: bool, + significand: u64, + starting_exp: i32, + ) -> Result { + self.eat_char(); + + let positive_exp = match try!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + true + } + b'-' => { + self.eat_char(); + false + } + _ => true, + }; + + // Make sure a digit follows the exponent place. + let mut exp = match try!(self.next_char_or_null()) { + c @ b'0'...b'9' => (c - b'0') as i32, + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + }; + + while let c @ b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + let digit = (c - b'0') as i32; + + if overflow!(exp * 10 + digit, i32::max_value()) { + return self.parse_exponent_overflow(positive, significand, positive_exp); + } + + exp = exp * 10 + digit; + } + + let final_exp = if positive_exp { + starting_exp.saturating_add(exp) + } else { + starting_exp.saturating_sub(exp) + }; + + self.f64_from_parts(positive, significand, final_exp) + } + + // This cold code should not be inlined into the middle of the hot + // exponent-parsing loop above. + #[cold] + #[inline(never)] + fn parse_exponent_overflow( + &mut self, + positive: bool, + significand: u64, + positive_exp: bool, + ) -> Result { + // Error instead of +/- infinity. + if significand != 0 && positive_exp { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + + while let b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + } + Ok(if positive { 0.0 } else { -0.0 }) + } + + fn parse_any_signed_number(&mut self) -> Result { + let peek = match try!(self.peek()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'-' => { + self.eat_char(); + self.parse_any_number(false) + } + b'0'...b'9' => self.parse_any_number(true), + _ => Err(self.peek_error(ErrorCode::InvalidNumber)), + }; + + let value = match try!(self.peek()) { + Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)), + None => value, + }; + + match value { + Ok(value) => Ok(value), + // The de::Error impl creates errors with unknown line and column. + // Fill in the position here by looking at the current index in the + // input. There is no way to tell whether this should call `error` + // or `peek_error` so pick the one that seems correct more often. + // Worst case, the position is off by one character. + Err(err) => Err(self.fix_position(err)), + } + } + + #[cfg(not(feature = "arbitrary_precision"))] + fn parse_any_number(&mut self, positive: bool) -> Result { + self.parse_integer(positive) + } + + #[cfg(feature = "arbitrary_precision")] + fn parse_any_number(&mut self, positive: bool) -> Result { + let mut buf = String::with_capacity(16); + if !positive { + buf.push('-'); + } + self.scan_integer(&mut buf)?; + Ok(ParserNumber::String(buf)) + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_or_null(&mut self, buf: &mut String) -> Result { + match try!(self.next_char()) { + Some(b) => { + buf.push(b as char); + Ok(b) + } + None => Ok(b'\x00'), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_integer(&mut self, buf: &mut String) -> Result<()> { + match try!(self.scan_or_null(buf)) { + b'0' => { + // There can be only one leading '0'. + match try!(self.peek_or_null()) { + b'0'...b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), + _ => self.scan_number(buf), + } + } + b'1'...b'9' => loop { + match try!(self.peek_or_null()) { + c @ b'0'...b'9' => { + self.eat_char(); + buf.push(c as char); + } + _ => { + return self.scan_number(buf); + } + } + }, + _ => Err(self.error(ErrorCode::InvalidNumber)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_number(&mut self, buf: &mut String) -> Result<()> { + match try!(self.peek_or_null()) { + b'.' => self.scan_decimal(buf), + b'e' | b'E' => self.scan_exponent(buf), + _ => Ok(()), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_decimal(&mut self, buf: &mut String) -> Result<()> { + self.eat_char(); + buf.push('.'); + + let mut at_least_one_digit = false; + while let c @ b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + at_least_one_digit = true; + } + + if !at_least_one_digit { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + + match try!(self.peek_or_null()) { + b'e' | b'E' => self.scan_exponent(buf), + _ => Ok(()), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn scan_exponent(&mut self, buf: &mut String) -> Result<()> { + self.eat_char(); + buf.push('e'); + + match try!(self.peek_or_null()) { + b'+' => { + self.eat_char(); + } + b'-' => { + self.eat_char(); + buf.push('-'); + } + _ => {} + } + + // Make sure a digit follows the exponent place. + match try!(self.scan_or_null(buf)) { + b'0'...b'9' => {} + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + while let c @ b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + buf.push(c as char); + } + + Ok(()) + } + + fn f64_from_parts( + &mut self, + positive: bool, + significand: u64, + mut exponent: i32, + ) -> Result { + let mut f = significand as f64; + loop { + match POW10.get(exponent.abs() as usize) { + Some(&pow) => { + if exponent >= 0 { + f *= pow; + if f.is_infinite() { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + } else { + f /= pow; + } + break; + } + None => { + if f == 0.0 { + break; + } + if exponent >= 0 { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + f /= 1e308; + exponent += 308; + } + } + } + Ok(if positive { f } else { -f }) + } + + fn parse_object_colon(&mut self) -> Result<()> { + match try!(self.parse_whitespace()) { + Some(b':') => { + self.eat_char(); + Ok(()) + } + Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + fn end_seq(&mut self) -> Result<()> { + match try!(self.parse_whitespace()) { + Some(b']') => { + self.eat_char(); + Ok(()) + } + Some(b',') => { + self.eat_char(); + match self.parse_whitespace() { + Ok(Some(b']')) => Err(self.peek_error(ErrorCode::TrailingComma)), + _ => Err(self.peek_error(ErrorCode::TrailingCharacters)), + } + } + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingList)), + } + } + + fn end_map(&mut self) -> Result<()> { + match try!(self.parse_whitespace()) { + Some(b'}') => { + self.eat_char(); + Ok(()) + } + Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)), + Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)), + } + } + + fn ignore_value(&mut self) -> Result<()> { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + match peek { + b'n' => { + self.eat_char(); + self.parse_ident(b"ull") + } + b't' => { + self.eat_char(); + self.parse_ident(b"rue") + } + b'f' => { + self.eat_char(); + self.parse_ident(b"alse") + } + b'-' => { + self.eat_char(); + self.ignore_integer() + } + b'0'...b'9' => self.ignore_integer(), + b'"' => { + self.eat_char(); + self.read.ignore_str() + } + b'[' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let res = self.ignore_seq(); + self.remaining_depth += 1; + res + } + b'{' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let res = self.ignore_map(); + self.remaining_depth += 1; + res + } + _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + } + } + + fn ignore_integer(&mut self) -> Result<()> { + match try!(self.next_char_or_null()) { + b'0' => { + // There can be only one leading '0'. + if let b'0'...b'9' = try!(self.peek_or_null()) { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + } + b'1'...b'9' => while let b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + }, + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + match try!(self.peek_or_null()) { + b'.' => self.ignore_decimal(), + b'e' | b'E' => self.ignore_exponent(), + _ => Ok(()), + } + } + + fn ignore_decimal(&mut self) -> Result<()> { + self.eat_char(); + + let mut at_least_one_digit = false; + while let b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + at_least_one_digit = true; + } + + if !at_least_one_digit { + return Err(self.peek_error(ErrorCode::InvalidNumber)); + } + + match try!(self.peek_or_null()) { + b'e' | b'E' => self.ignore_exponent(), + _ => Ok(()), + } + } + + fn ignore_exponent(&mut self) -> Result<()> { + self.eat_char(); + + match try!(self.peek_or_null()) { + b'+' | b'-' => self.eat_char(), + _ => {} + } + + // Make sure a digit follows the exponent place. + match try!(self.next_char_or_null()) { + b'0'...b'9' => {} + _ => { + return Err(self.error(ErrorCode::InvalidNumber)); + } + } + + while let b'0'...b'9' = try!(self.peek_or_null()) { + self.eat_char(); + } + + Ok(()) + } + + fn ignore_seq(&mut self) -> Result<()> { + let mut first = true; + + loop { + match try!(self.parse_whitespace()) { + Some(b']') => { + self.eat_char(); + return Ok(()); + } + Some(b',') if !first => { + self.eat_char(); + } + Some(_) => { + if first { + first = false; + } else { + return Err(self.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + } + } + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingList)); + } + } + + try!(self.ignore_value()); + } + } + + fn ignore_map(&mut self) -> Result<()> { + let mut first = true; + + loop { + let peek = match try!(self.parse_whitespace()) { + Some(b'}') => { + self.eat_char(); + return Ok(()); + } + Some(b',') if !first => { + self.eat_char(); + try!(self.parse_whitespace()) + } + Some(b) => { + if first { + first = false; + Some(b) + } else { + return Err(self.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + } + } + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingObject)); + } + }; + + match peek { + Some(b'"') => { + self.eat_char(); + try!(self.read.ignore_str()); + } + Some(_) => { + return Err(self.peek_error(ErrorCode::KeyMustBeAString)); + } + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingObject)); + } + } + + match try!(self.parse_whitespace()) { + Some(b':') => { + self.eat_char(); + try!(self.ignore_value()); + } + Some(_) => { + return Err(self.peek_error(ErrorCode::ExpectedColon)); + } + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingObject)); + } + } + } + } +} + +impl FromStr for Number { + type Err = Error; + + fn from_str(s: &str) -> result::Result { + Deserializer::from_str(s) + .parse_any_signed_number() + .map(Into::into) + } +} + +#[cfg_attr(rustfmt, rustfmt_skip)] +static POW10: [f64; 309] = + [1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, + 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019, + 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029, + 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039, + 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049, + 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059, + 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069, + 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079, + 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089, + 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099, + 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, + 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, + 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, + 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, + 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, + 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, + 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, + 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, + 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, + 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, + 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, + 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, + 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, + 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, + 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, + 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, + 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, + 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, + 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, + 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, + 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308]; + +macro_rules! deserialize_prim_number { + ($method:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_prim_number(visitor) + } + } +} + +impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'n' => { + self.eat_char(); + try!(self.parse_ident(b"ull")); + visitor.visit_unit() + } + b't' => { + self.eat_char(); + try!(self.parse_ident(b"rue")); + visitor.visit_bool(true) + } + b'f' => { + self.eat_char(); + try!(self.parse_ident(b"alse")); + visitor.visit_bool(false) + } + b'-' => { + self.eat_char(); + try!(self.parse_any_number(false)).visit(visitor) + } + b'0'...b'9' => try!(self.parse_any_number(true)).visit(visitor), + b'"' => { + self.eat_char(); + self.str_buf.clear(); + match try!(self.read.parse_str(&mut self.str_buf)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + b'[' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + }; + + match value { + Ok(value) => Ok(value), + // The de::Error impl creates errors with unknown line and column. + // Fill in the position here by looking at the current index in the + // input. There is no way to tell whether this should call `error` + // or `peek_error` so pick the one that seems correct more often. + // Worst case, the position is off by one character. + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b't' => { + self.eat_char(); + try!(self.parse_ident(b"rue")); + visitor.visit_bool(true) + } + b'f' => { + self.eat_char(); + try!(self.parse_ident(b"alse")); + visitor.visit_bool(false) + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + deserialize_prim_number!(deserialize_i8); + deserialize_prim_number!(deserialize_i16); + deserialize_prim_number!(deserialize_i32); + deserialize_prim_number!(deserialize_i64); + deserialize_prim_number!(deserialize_u8); + deserialize_prim_number!(deserialize_u16); + deserialize_prim_number!(deserialize_u32); + deserialize_prim_number!(deserialize_u64); + deserialize_prim_number!(deserialize_f32); + deserialize_prim_number!(deserialize_f64); + + serde_if_integer128! { + fn deserialize_i128(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let mut buf = String::new(); + + match try!(self.parse_whitespace()) { + Some(b'-') => { + self.eat_char(); + buf.push('-'); + } + Some(_) => {} + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + try!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_i128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_u128(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match try!(self.parse_whitespace()) { + Some(b'-') => { + return Err(self.peek_error(ErrorCode::NumberOutOfRange)); + } + Some(_) => {} + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + } + + let mut buf = String::new(); + try!(self.scan_integer128(&mut buf)); + + let value = match buf.parse() { + Ok(int) => visitor.visit_u128(int), + Err(_) => { + return Err(self.error(ErrorCode::NumberOutOfRange)); + } + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'"' => { + self.eat_char(); + self.str_buf.clear(); + match try!(self.read.parse_str(&mut self.str_buf)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + /// Parses a JSON string as bytes. Note that this function does not check + /// whether the bytes represent a valid UTF-8 string. + /// + /// The relevant part of the JSON specification is Section 8.2 of [RFC + /// 7159]: + /// + /// > When all the strings represented in a JSON text are composed entirely + /// > of Unicode characters (however escaped), then that JSON text is + /// > interoperable in the sense that all software implementations that + /// > parse it will agree on the contents of names and of string values in + /// > objects and arrays. + /// > + /// > However, the ABNF in this specification allows member names and string + /// > values to contain bit sequences that cannot encode Unicode characters; + /// > for example, "\uDEAD" (a single unpaired UTF-16 surrogate). Instances + /// > of this have been observed, for example, when a library truncates a + /// > UTF-16 string without checking whether the truncation split a + /// > surrogate pair. The behavior of software that receives JSON texts + /// > containing such values is unpredictable; for example, implementations + /// > might return different values for the length of a string value or even + /// > suffer fatal runtime exceptions. + /// + /// [RFC 7159]: https://tools.ietf.org/html/rfc7159 + /// + /// The behavior of serde_json is specified to fail on non-UTF-8 strings + /// when deserializing into Rust UTF-8 string types such as String, and + /// succeed with non-UTF-8 bytes when deserializing using this method. + /// + /// Escape sequences are processed as usual, and for `\uXXXX` escapes it is + /// still checked if the hex number represents a valid Unicode code point. + /// + /// # Examples + /// + /// You can use this to parse JSON strings containing invalid UTF-8 bytes. + /// + /// ```rust + /// extern crate serde_json; + /// extern crate serde_bytes; + /// + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() -> Result<(), serde_json::Error> { + /// let json_data = b"\"some bytes: \xe5\x00\xe5\""; + /// let bytes: ByteBuf = serde_json::from_slice(json_data)?; + /// + /// assert_eq!(b'\xe5', bytes[12]); + /// assert_eq!(b'\0', bytes[13]); + /// assert_eq!(b'\xe5', bytes[14]); + /// + /// Ok(()) + /// } + /// # + /// # fn main() { + /// # look_at_bytes().unwrap(); + /// # } + /// ``` + /// + /// Backslash escape sequences like `\n` are still interpreted and required + /// to be valid, and `\u` escape sequences are required to represent valid + /// Unicode code points. + /// + /// ```rust + /// extern crate serde_json; + /// extern crate serde_bytes; + /// + /// use serde_bytes::ByteBuf; + /// + /// fn look_at_bytes() { + /// let json_data = b"\"invalid unicode surrogate: \\uD801\""; + /// let parsed: Result = serde_json::from_slice(json_data); + /// + /// assert!(parsed.is_err()); + /// + /// let expected_msg = "unexpected end of hex escape at line 1 column 35"; + /// assert_eq!(expected_msg, parsed.unwrap_err().to_string()); + /// } + /// # + /// # fn main() { + /// # look_at_bytes(); + /// # } + /// ``` + fn deserialize_bytes(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'"' => { + self.eat_char(); + self.str_buf.clear(); + match try!(self.read.parse_str_raw(&mut self.str_buf)) { + Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), + Reference::Copied(b) => visitor.visit_bytes(b), + } + } + b'[' => self.deserialize_seq(visitor), + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + #[inline] + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + /// Parses a `null` as a None, and any other values as a `Some(...)`. + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match try!(self.parse_whitespace()) { + Some(b'n') => { + self.eat_char(); + try!(self.parse_ident(b"ull")); + visitor.visit_none() + } + _ => visitor.visit_some(self), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'n' => { + self.eat_char(); + try!(self.parse_ident(b"ull")); + visitor.visit_unit() + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + /// Parses a newtype struct as the underlying value. + #[inline] + fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'[' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'{' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + let peek = match try!(self.parse_whitespace()) { + Some(b) => b, + None => { + return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); + } + }; + + let value = match peek { + b'[' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_seq(SeqAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_seq()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + b'{' => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let ret = visitor.visit_map(MapAccess::new(self)); + + self.remaining_depth += 1; + + match (ret, self.end_map()) { + (Ok(ret), Ok(())) => Ok(ret), + (Err(err), _) | (_, Err(err)) => Err(err), + } + } + _ => Err(self.peek_invalid_type(&visitor)), + }; + + match value { + Ok(value) => Ok(value), + Err(err) => Err(self.fix_position(err)), + } + } + + /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight + /// value, a `[..]`, or a `{..}`. + #[inline] + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + match try!(self.parse_whitespace()) { + Some(b'{') => { + self.remaining_depth -= 1; + if self.remaining_depth == 0 { + return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); + } + + self.eat_char(); + let value = try!(visitor.visit_enum(VariantAccess::new(self))); + + self.remaining_depth += 1; + + match try!(self.parse_whitespace()) { + Some(b'}') => { + self.eat_char(); + Ok(value) + } + Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)), + None => Err(self.error(ErrorCode::EofWhileParsingObject)), + } + } + Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)), + Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), + None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + try!(self.ignore_value()); + visitor.visit_unit() + } +} + +struct SeqAccess<'a, R: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, R: 'a> SeqAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + SeqAccess { + de: de, + first: true, + } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result> + where + T: de::DeserializeSeed<'de>, + { + let peek = match try!(self.de.parse_whitespace()) { + Some(b']') => { + return Ok(None); + } + Some(b',') if !self.first => { + self.de.eat_char(); + try!(self.de.parse_whitespace()) + } + Some(b) => { + if self.first { + self.first = false; + Some(b) + } else { + return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + } + } + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); + } + }; + + match peek { + Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Ok(Some(try!(seed.deserialize(&mut *self.de)))), + None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + } + } +} + +struct MapAccess<'a, R: 'a> { + de: &'a mut Deserializer, + first: bool, +} + +impl<'a, R: 'a> MapAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + MapAccess { + de: de, + first: true, + } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result> + where + K: de::DeserializeSeed<'de>, + { + let peek = match try!(self.de.parse_whitespace()) { + Some(b'}') => { + return Ok(None); + } + Some(b',') if !self.first => { + self.de.eat_char(); + try!(self.de.parse_whitespace()) + } + Some(b) => { + if self.first { + self.first = false; + Some(b) + } else { + return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + } + } + None => { + return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); + } + }; + + match peek { + Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), + Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), + None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + try!(self.de.parse_object_colon()); + + seed.deserialize(&mut *self.de) + } +} + +struct VariantAccess<'a, R: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, R: 'a> VariantAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + VariantAccess { de: de } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for VariantAccess<'a, R> { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> + where + V: de::DeserializeSeed<'de>, + { + let val = try!(seed.deserialize(&mut *self.de)); + try!(self.de.parse_object_colon()); + Ok((val, self)) + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for VariantAccess<'a, R> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + de::Deserialize::deserialize(self.de) + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self.de) + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_seq(self.de, visitor) + } + + fn struct_variant(self, fields: &'static [&'static str], visitor: V) -> Result + where + V: de::Visitor<'de>, + { + de::Deserializer::deserialize_struct(self.de, "", fields, visitor) + } +} + +struct UnitVariantAccess<'a, R: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, R: 'a> UnitVariantAccess<'a, R> { + fn new(de: &'a mut Deserializer) -> Self { + UnitVariantAccess { de: de } + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, R> { + type Error = Error; + type Variant = Self; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> + where + V: de::DeserializeSeed<'de>, + { + let variant = try!(seed.deserialize(&mut *self.de)); + Ok((variant, self)) + } +} + +impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, R> { + type Error = Error; + + fn unit_variant(self) -> Result<()> { + Ok(()) + } + + fn newtype_variant_seed(self, _seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant(self, _len: usize, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} + +/// Only deserialize from this after peeking a '"' byte! Otherwise it may +/// deserialize invalid JSON successfully. +struct MapKey<'a, R: 'a> { + de: &'a mut Deserializer, +} + +macro_rules! deserialize_integer_key { + ($method:ident => $visit:ident) => { + fn $method(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + self.de.str_buf.clear(); + let string = try!(self.de.read.parse_str(&mut self.de.str_buf)); + match (string.parse(), string) { + (Ok(integer), _) => visitor.$visit(integer), + (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), + (Err(_), Reference::Copied(s)) => visitor.visit_str(s), + } + } + } +} + +impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R> +where + R: Read<'de>, +{ + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.eat_char(); + self.de.str_buf.clear(); + match try!(self.de.read.parse_str(&mut self.de.str_buf)) { + Reference::Borrowed(s) => visitor.visit_borrowed_str(s), + Reference::Copied(s) => visitor.visit_str(s), + } + } + + deserialize_integer_key!(deserialize_i8 => visit_i8); + deserialize_integer_key!(deserialize_i16 => visit_i16); + deserialize_integer_key!(deserialize_i32 => visit_i32); + deserialize_integer_key!(deserialize_i64 => visit_i64); + deserialize_integer_key!(deserialize_u8 => visit_u8); + deserialize_integer_key!(deserialize_u16 => visit_u16); + deserialize_integer_key!(deserialize_u32 => visit_u32); + deserialize_integer_key!(deserialize_u64 => visit_u64); + + serde_if_integer128! { + deserialize_integer_key!(deserialize_i128 => visit_i128); + deserialize_integer_key!(deserialize_u128 => visit_u128); + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + #[inline] + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_enum(name, variants, visitor) + } + + #[inline] + fn deserialize_bytes(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_bytes(visitor) + } + + #[inline] + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + self.de.deserialize_bytes(visitor) + } + + forward_to_deserialize_any! { + bool f32 f64 char str string unit unit_struct seq tuple tuple_struct map + struct identifier ignored_any + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// Iterator that deserializes a stream into multiple JSON values. +/// +/// A stream deserializer can be created from any JSON deserializer using the +/// `Deserializer::into_iter` method. +/// +/// The data can consist of any JSON value. Values need to be a self-delineating value e.g. +/// arrays, objects, or strings, or be followed by whitespace or a self-delineating value. +/// +/// ```rust +/// extern crate serde_json; +/// +/// use serde_json::{Deserializer, Value}; +/// +/// fn main() { +/// let data = "{\"k\": 3}1\"cool\"\"stuff\" 3{} [0, 1, 2]"; +/// +/// let stream = Deserializer::from_str(data).into_iter::(); +/// +/// for value in stream { +/// println!("{}", value.unwrap()); +/// } +/// } +/// ``` +pub struct StreamDeserializer<'de, R, T> { + de: Deserializer, + offset: usize, + output: PhantomData, + lifetime: PhantomData<&'de ()>, +} + +impl<'de, R, T> StreamDeserializer<'de, R, T> +where + R: read::Read<'de>, + T: de::Deserialize<'de>, +{ + /// Create a JSON stream deserializer from one of the possible serde_json + /// input sources. + /// + /// Typically it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str(...).into_iter() + /// - Deserializer::from_bytes(...).into_iter() + /// - Deserializer::from_reader(...).into_iter() + pub fn new(read: R) -> Self { + let offset = read.byte_offset(); + StreamDeserializer { + de: Deserializer::new(read), + offset: offset, + output: PhantomData, + lifetime: PhantomData, + } + } + + /// Returns the number of bytes so far deserialized into a successful `T`. + /// + /// If a stream deserializer returns an EOF error, new data can be joined to + /// `old_data[stream.byte_offset()..]` to try again. + /// + /// ```rust + /// let data = b"[0] [1] ["; + /// + /// let de = serde_json::Deserializer::from_slice(data); + /// let mut stream = de.into_iter::>(); + /// assert_eq!(0, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // [0] + /// assert_eq!(3, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // [1] + /// assert_eq!(7, stream.byte_offset()); + /// + /// println!("{:?}", stream.next()); // error + /// assert_eq!(8, stream.byte_offset()); + /// + /// // If err.is_eof(), can join the remaining data to new data and continue. + /// let remaining = &data[stream.byte_offset()..]; + /// ``` + /// + /// *Note:* In the future this method may be changed to return the number of + /// bytes so far deserialized into a successful T *or* syntactically valid + /// JSON skipped over due to a type error. See [serde-rs/json#70] for an + /// example illustrating this. + /// + /// [serde-rs/json#70]: https://github.com/serde-rs/json/issues/70 + pub fn byte_offset(&self) -> usize { + self.offset + } + + fn peek_end_of_value(&mut self) -> Result<()> { + match try!(self.de.peek()) { + Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b'"') | Some(b'[') + | Some(b']') | Some(b'{') | Some(b'}') | Some(b',') | Some(b':') | None => Ok(()), + Some(_) => { + let position = self.de.read.peek_position(); + Err(Error::syntax( + ErrorCode::TrailingCharacters, + position.line, + position.column, + )) + } + } + } +} + +impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T> +where + R: Read<'de>, + T: de::Deserialize<'de>, +{ + type Item = Result; + + fn next(&mut self) -> Option> { + // skip whitespaces, if any + // this helps with trailing whitespaces, since whitespaces between + // values are handled for us. + match self.de.parse_whitespace() { + Ok(None) => { + self.offset = self.de.read.byte_offset(); + None + } + Ok(Some(b)) => { + // If the value does not have a clear way to show the end of the value + // (like numbers, null, true etc.) we have to look for whitespace or + // the beginning of a self-delineated value. + let self_delineated_value = match b { + b'[' | b'"' | b'{' => true, + _ => false, + }; + self.offset = self.de.read.byte_offset(); + let result = de::Deserialize::deserialize(&mut self.de); + + Some(match result { + Ok(value) => { + self.offset = self.de.read.byte_offset(); + if self_delineated_value { + Ok(value) + } else { + self.peek_end_of_value().map(|_| value) + } + } + Err(e) => Err(e), + }) + } + Err(e) => Some(Err(e)), + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +fn from_trait<'de, R, T>(read: R) -> Result +where + R: Read<'de>, + T: de::Deserialize<'de>, +{ + let mut de = Deserializer::new(read); + let value = try!(de::Deserialize::deserialize(&mut de)); + + // Make sure the whole stream has been consumed. + try!(de.end()); + Ok(value) +} + +/// Deserialize an instance of type `T` from an IO stream of JSON. +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde_derive; +/// +/// extern crate serde; +/// extern crate serde_json; +/// +/// use std::error::Error; +/// use std::fs::File; +/// use std::path::Path; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn read_user_from_file>(path: P) -> Result> { +/// // Open the file in read-only mode. +/// let file = File::open(path)?; +/// +/// // Read the JSON contents of the file as an instance of `User`. +/// let u = serde_json::from_reader(file)?; +/// +/// // Return the `User`. +/// Ok(u) +/// } +/// +/// fn main() { +/// # } +/// # fn fake_main() { +/// let u = read_user_from_file("test.json").unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +pub fn from_reader(rdr: R) -> Result +where + R: io::Read, + T: de::DeserializeOwned, +{ + from_trait(read::IoRead::new(rdr)) +} + +/// Deserialize an instance of type `T` from bytes of JSON text. +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde_derive; +/// +/// extern crate serde; +/// extern crate serde_json; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&[u8]` +/// let j = b"{ +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_slice(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +pub fn from_slice<'a, T>(v: &'a [u8]) -> Result +where + T: de::Deserialize<'a>, +{ + from_trait(read::SliceRead::new(v)) +} + +/// Deserialize an instance of type `T` from a string of JSON text. +/// +/// # Errors +/// +/// This conversion can fail if the structure of the input does not match the +/// structure expected by `T`, for example if `T` is a struct type but the input +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde_derive; +/// +/// extern crate serde; +/// extern crate serde_json; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `&str` +/// let j = "{ +/// \"fingerprint\": \"0xF9BA143B95FF6D82\", +/// \"location\": \"Menlo Park, CA\" +/// }"; +/// +/// let u: User = serde_json::from_str(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +pub fn from_str<'a, T>(s: &'a str) -> Result +where + T: de::Deserialize<'a>, +{ + from_trait(read::StrRead::new(s)) +} diff --git a/third_party/rust/serde_json/src/error.rs b/third_party/rust/serde_json/src/error.rs new file mode 100644 index 000000000000..61636dca1eb3 --- /dev/null +++ b/third_party/rust/serde_json/src/error.rs @@ -0,0 +1,429 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! When serializing or deserializing JSON goes wrong. + +use std::error; +use std::fmt::{self, Debug, Display}; +use std::io; +use std::result; + +use serde::de; +use serde::ser; + +/// This type represents all possible errors that can occur when serializing or +/// deserializing JSON data. +pub struct Error { + /// This `Box` allows us to keep the size of `Error` as small as possible. A + /// larger `Error` type was substantially slower due to all the functions + /// that pass around `Result`. + err: Box, +} + +/// Alias for a `Result` with the error type `serde_json::Error`. +pub type Result = result::Result; + +impl Error { + /// One-based line number at which the error was detected. + /// + /// Characters in the first line of the input (before the first newline + /// character) are in line 1. + pub fn line(&self) -> usize { + self.err.line + } + + /// One-based column number at which the error was detected. + /// + /// The first character in the input and any characters immediately + /// following a newline character are in column 1. + /// + /// Note that errors may occur in column 0, for example if a read from an IO + /// stream fails immediately following a previously read newline character. + pub fn column(&self) -> usize { + self.err.column + } + + /// Categorizes the cause of this error. + /// + /// - `Category::Io` - failure to read or write bytes on an IO stream + /// - `Category::Syntax` - input that is not syntactically valid JSON + /// - `Category::Data` - input data that is semantically incorrect + /// - `Category::Eof` - unexpected end of the input data + pub fn classify(&self) -> Category { + match self.err.code { + ErrorCode::Message(_) => Category::Data, + ErrorCode::Io(_) => Category::Io, + ErrorCode::EofWhileParsingList + | ErrorCode::EofWhileParsingObject + | ErrorCode::EofWhileParsingString + | ErrorCode::EofWhileParsingValue => Category::Eof, + ErrorCode::ExpectedColon + | ErrorCode::ExpectedListCommaOrEnd + | ErrorCode::ExpectedObjectCommaOrEnd + | ErrorCode::ExpectedObjectOrArray + | ErrorCode::ExpectedSomeIdent + | ErrorCode::ExpectedSomeValue + | ErrorCode::ExpectedSomeString + | ErrorCode::InvalidEscape + | ErrorCode::InvalidNumber + | ErrorCode::NumberOutOfRange + | ErrorCode::InvalidUnicodeCodePoint + | ErrorCode::ControlCharacterWhileParsingString + | ErrorCode::KeyMustBeAString + | ErrorCode::LoneLeadingSurrogateInHexEscape + | ErrorCode::TrailingComma + | ErrorCode::TrailingCharacters + | ErrorCode::UnexpectedEndOfHexEscape + | ErrorCode::RecursionLimitExceeded => Category::Syntax, + } + } + + /// Returns true if this error was caused by a failure to read or write + /// bytes on an IO stream. + pub fn is_io(&self) -> bool { + self.classify() == Category::Io + } + + /// Returns true if this error was caused by input that was not + /// syntactically valid JSON. + pub fn is_syntax(&self) -> bool { + self.classify() == Category::Syntax + } + + /// Returns true if this error was caused by input data that was + /// semantically incorrect. + /// + /// For example, JSON containing a number is semantically incorrect when the + /// type being deserialized into holds a String. + pub fn is_data(&self) -> bool { + self.classify() == Category::Data + } + + /// Returns true if this error was caused by prematurely reaching the end of + /// the input data. + /// + /// Callers that process streaming input may be interested in retrying the + /// deserialization once more data is available. + pub fn is_eof(&self) -> bool { + self.classify() == Category::Eof + } +} + +/// Categorizes the cause of a `serde_json::Error`. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Category { + /// The error was caused by a failure to read or write bytes on an IO + /// stream. + Io, + + /// The error was caused by input that was not syntactically valid JSON. + Syntax, + + /// The error was caused by input data that was semantically incorrect. + /// + /// For example, JSON containing a number is semantically incorrect when the + /// type being deserialized into holds a String. + Data, + + /// The error was caused by prematurely reaching the end of the input data. + /// + /// Callers that process streaming input may be interested in retrying the + /// deserialization once more data is available. + Eof, +} + +#[cfg_attr(feature = "cargo-clippy", allow(fallible_impl_from))] +impl From for io::Error { + /// Convert a `serde_json::Error` into an `io::Error`. + /// + /// JSON syntax and data errors are turned into `InvalidData` IO errors. + /// EOF errors are turned into `UnexpectedEof` IO errors. + /// + /// ```rust + /// use std::io; + /// + /// enum MyError { + /// Io(io::Error), + /// Json(serde_json::Error), + /// } + /// + /// impl From for MyError { + /// fn from(err: serde_json::Error) -> MyError { + /// use serde_json::error::Category; + /// match err.classify() { + /// Category::Io => { + /// MyError::Io(err.into()) + /// } + /// Category::Syntax | Category::Data | Category::Eof => { + /// MyError::Json(err) + /// } + /// } + /// } + /// } + /// ``` + fn from(j: Error) -> Self { + if let ErrorCode::Io(err) = j.err.code { + err + } else { + match j.classify() { + Category::Io => unreachable!(), + Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j), + Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j), + } + } + } +} + +struct ErrorImpl { + code: ErrorCode, + line: usize, + column: usize, +} + +// Not public API. Should be pub(crate). +#[doc(hidden)] +pub enum ErrorCode { + /// Catchall for syntax error messages + Message(Box), + + /// Some IO error occurred while serializing or deserializing. + Io(io::Error), + + /// EOF while parsing a list. + EofWhileParsingList, + + /// EOF while parsing an object. + EofWhileParsingObject, + + /// EOF while parsing a string. + EofWhileParsingString, + + /// EOF while parsing a JSON value. + EofWhileParsingValue, + + /// Expected this character to be a `':'`. + ExpectedColon, + + /// Expected this character to be either a `','` or a `']'`. + ExpectedListCommaOrEnd, + + /// Expected this character to be either a `','` or a `'}'`. + ExpectedObjectCommaOrEnd, + + /// Expected this character to be either a `'{'` or a `'['`. + ExpectedObjectOrArray, + + /// Expected to parse either a `true`, `false`, or a `null`. + ExpectedSomeIdent, + + /// Expected this character to start a JSON value. + ExpectedSomeValue, + + /// Expected this character to start a JSON string. + ExpectedSomeString, + + /// Invalid hex escape code. + InvalidEscape, + + /// Invalid number. + InvalidNumber, + + /// Number is bigger than the maximum value of its type. + NumberOutOfRange, + + /// Invalid unicode code point. + InvalidUnicodeCodePoint, + + /// Control character found while parsing a string. + ControlCharacterWhileParsingString, + + /// Object key is not a string. + KeyMustBeAString, + + /// Lone leading surrogate in hex escape. + LoneLeadingSurrogateInHexEscape, + + /// JSON has a comma after the last value in an array or map. + TrailingComma, + + /// JSON has non-whitespace trailing characters after the value. + TrailingCharacters, + + /// Unexpected end of hex excape. + UnexpectedEndOfHexEscape, + + /// Encountered nesting of JSON maps and arrays more than 128 layers deep. + RecursionLimitExceeded, +} + +impl Error { + // Not public API. Should be pub(crate). + #[doc(hidden)] + #[cold] + pub fn syntax(code: ErrorCode, line: usize, column: usize) -> Self { + Error { + err: Box::new(ErrorImpl { + code: code, + line: line, + column: column, + }), + } + } + + // Not public API. Should be pub(crate). + // + // Update `eager_json` crate when this function changes. + #[doc(hidden)] + #[cold] + pub fn io(error: io::Error) -> Self { + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Io(error), + line: 0, + column: 0, + }), + } + } + + // Not public API. Should be pub(crate). + #[doc(hidden)] + #[cold] + pub fn fix_position(self, f: F) -> Self + where + F: FnOnce(ErrorCode) -> Error, + { + if self.err.line == 0 { + f(self.err.code) + } else { + self + } + } +} + +impl Display for ErrorCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ErrorCode::Message(ref msg) => f.write_str(msg), + ErrorCode::Io(ref err) => Display::fmt(err, f), + ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"), + ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"), + ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"), + ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"), + ErrorCode::ExpectedColon => f.write_str("expected `:`"), + ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"), + ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"), + ErrorCode::ExpectedObjectOrArray => f.write_str("expected `{` or `[`"), + ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), + ErrorCode::ExpectedSomeValue => f.write_str("expected value"), + ErrorCode::ExpectedSomeString => f.write_str("expected string"), + ErrorCode::InvalidEscape => f.write_str("invalid escape"), + ErrorCode::InvalidNumber => f.write_str("invalid number"), + ErrorCode::NumberOutOfRange => f.write_str("number out of range"), + ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"), + ErrorCode::ControlCharacterWhileParsingString => { + f.write_str("control character (\\u0000-\\u001F) found while parsing a string") + } + ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), + ErrorCode::LoneLeadingSurrogateInHexEscape => { + f.write_str("lone leading surrogate in hex escape") + } + ErrorCode::TrailingComma => f.write_str("trailing comma"), + ErrorCode::TrailingCharacters => f.write_str("trailing characters"), + ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"), + ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), + } + } +} + +impl error::Error for Error { + fn description(&self) -> &str { + match self.err.code { + ErrorCode::Io(ref err) => error::Error::description(err), + _ => { + // If you want a better message, use Display::fmt or to_string(). + "JSON error" + } + } + } + + fn cause(&self) -> Option<&error::Error> { + match self.err.code { + ErrorCode::Io(ref err) => Some(err), + _ => None, + } + } +} + +impl Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&*self.err, f) + } +} + +impl Display for ErrorImpl { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.line == 0 { + Display::fmt(&self.code, f) + } else { + write!( + f, + "{} at line {} column {}", + self.code, self.line, self.column + ) + } + } +} + +// Remove two layers of verbosity from the debug representation. Humans often +// end up seeing this representation because it is what unwrap() shows. +impl Debug for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Error({:?}, line: {}, column: {})", + self.err.code.to_string(), + self.err.line, + self.err.column + ) + } +} + +impl de::Error for Error { + #[cold] + fn custom(msg: T) -> Error { + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Message(msg.to_string().into_boxed_str()), + line: 0, + column: 0, + }), + } + } + + #[cold] + fn invalid_type(unexp: de::Unexpected, exp: &de::Expected) -> Self { + if let de::Unexpected::Unit = unexp { + Error::custom(format_args!("invalid type: null, expected {}", exp)) + } else { + Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp)) + } + } +} + +impl ser::Error for Error { + #[cold] + fn custom(msg: T) -> Error { + Error { + err: Box::new(ErrorImpl { + code: ErrorCode::Message(msg.to_string().into_boxed_str()), + line: 0, + column: 0, + }), + } + } +} diff --git a/third_party/rust/serde_json/src/iter.rs b/third_party/rust/serde_json/src/iter.rs new file mode 100644 index 000000000000..344e8a420acd --- /dev/null +++ b/third_party/rust/serde_json/src/iter.rs @@ -0,0 +1,78 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::io; + +pub struct LineColIterator { + iter: I, + + /// Index of the current line. Characters in the first line of the input + /// (before the first newline character) are in line 1. + line: usize, + + /// Index of the current column. The first character in the input and any + /// characters immediately following a newline character are in column 1. + /// The column is 0 immediately after a newline character has been read. + col: usize, + + /// Byte offset of the start of the current line. This is the sum of lenghts + /// of all previous lines. Keeping track of things this way allows efficient + /// computation of the current line, column, and byte offset while only + /// updating one of the counters in `next()` in the common case. + start_of_line: usize, +} + +impl LineColIterator +where + I: Iterator>, +{ + pub fn new(iter: I) -> LineColIterator { + LineColIterator { + iter: iter, + line: 1, + col: 0, + start_of_line: 0, + } + } + + pub fn line(&self) -> usize { + self.line + } + + pub fn col(&self) -> usize { + self.col + } + + pub fn byte_offset(&self) -> usize { + self.start_of_line + self.col + } +} + +impl Iterator for LineColIterator +where + I: Iterator>, +{ + type Item = io::Result; + + fn next(&mut self) -> Option> { + match self.iter.next() { + None => None, + Some(Ok(b'\n')) => { + self.start_of_line += self.col + 1; + self.line += 1; + self.col = 0; + Some(Ok(b'\n')) + } + Some(Ok(c)) => { + self.col += 1; + Some(Ok(c)) + } + Some(Err(e)) => Some(Err(e)), + } + } +} diff --git a/third_party/rust/serde_json/src/lib.rs b/third_party/rust/serde_json/src/lib.rs new file mode 100644 index 000000000000..4c9ac4f314ee --- /dev/null +++ b/third_party/rust/serde_json/src/lib.rs @@ -0,0 +1,391 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! # Serde JSON +//! +//! JSON is a ubiquitous open-standard format that uses human-readable text to +//! transmit data objects consisting of key-value pairs. +//! +//! ```json,ignore +//! { +//! "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 +//! # use serde_json::{Number, Map}; +//! # +//! # #[allow(dead_code)] +//! enum Value { +//! Null, +//! Bool(bool), +//! Number(Number), +//! String(String), +//! Array(Vec), +//! Object(Map), +//! } +//! ``` +//! +//! A string of JSON data can be parsed into a `serde_json::Value` by the +//! [`serde_json::from_str`][from_str] function. There is also +//! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and +//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or +//! a TCP stream. +//! +//! ```rust +//! extern crate serde_json; +//! +//! use serde_json::{Value, Error}; +//! +//! fn untyped_example() -> Result<(), Error> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#"{ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # untyped_example().unwrap(); +//! # } +//! ``` +//! +//! The result of square bracket indexing like `v["name"]` is a borrow of the +//! data at that index, so the type is `&Value`. A JSON map can be indexed with +//! string keys, while a JSON array can be indexed with integer keys. If the +//! type of the data is not right for the type with which it is being indexed, +//! or if a map does not contain the key being indexed, or if the index into a +//! vector is out of bounds, the returned element is `Value::Null`. +//! +//! When a `Value` is printed, it is printed as a JSON string. So in the code +//! above, the output looks like `Please call "John Doe" at the number "+44 +//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value` +//! containing a JSON string and its JSON representation is `"John Doe"`. +//! Printing as a plain string without quotation marks involves converting from +//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of +//! `Value` as described in the following section. +//! +//! [`as_str()`]: https://docs.serde.rs/serde_json/enum.Value.html#method.as_str +//! +//! The `Value` representation is sufficient for very basic tasks but can be +//! tedious to work with for anything more significant. Error handling is +//! verbose to implement correctly, for example imagine trying to detect the +//! presence of unrecognized fields in the input data. The compiler is powerless +//! to help you when you make a mistake, for example imagine typoing `v["name"]` +//! as `v["nmae"]` in one of the dozens of places it is used in your code. +//! +//! # Parsing JSON as strongly typed data structures +//! +//! Serde provides a powerful way of mapping JSON data into Rust data structures +//! largely automatically. +//! +//! ```rust +//! extern crate serde; +//! extern crate serde_json; +//! +//! #[macro_use] +//! extern crate serde_derive; +//! +//! use serde_json::Error; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Person { +//! name: String, +//! age: u8, +//! phones: Vec, +//! } +//! +//! fn typed_example() -> Result<(), Error> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#"{ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into a Person object. This is exactly the +//! // same function as the one that produced serde_json::Value above, but +//! // now we are asking it for a Person as output. +//! let p: Person = serde_json::from_str(data)?; +//! +//! // Do things just like with any other Rust data structure. +//! println!("Please call {} at the number {}", p.name, p.phones[0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # typed_example().unwrap(); +//! # } +//! ``` +//! +//! This is the same `serde_json::from_str` function as before, but this time we +//! assign the return value to a variable of type `Person` so Serde will +//! automatically interpret the input data as a `Person` and produce informative +//! error messages if the layout does not conform to what a `Person` is expected +//! to look like. +//! +//! Any type that implements Serde's `Deserialize` trait can be deserialized +//! this way. This includes built-in Rust standard library types like `Vec` +//! and `HashMap`, as well as any structs or enums annotated with +//! `#[derive(Deserialize)]`. +//! +//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us +//! use it correctly like they do for any other Rust code. The IDE can +//! autocomplete field names to prevent typos, which was impossible in the +//! `serde_json::Value` representation. And the Rust compiler can check that +//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a +//! `Vec` so indexing into it makes sense and produces a `String`. +//! +//! # Constructing JSON values +//! +//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +//! objects with very natural JSON syntax. In order to use this macro, +//! `serde_json` needs to be imported with the `#[macro_use]` attribute. +//! +//! ```rust +//! #[macro_use] +//! extern crate serde_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. +//! +//! ```rust +//! # #[macro_use] +//! # extern crate serde_json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! # fn main() { +//! 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()) +//! ] +//! }); +//! # let _ = john; +//! # } +//! ``` +//! +//! This is amazingly convenient but we have the problem we had before with +//! `Value` which is that the IDE and Rust compiler cannot help us if we get it +//! wrong. Serde JSON provides a better way of serializing strongly-typed data +//! structures into JSON text. +//! +//! # Creating JSON by serializing data structures +//! +//! A data structure can be converted to a JSON string by +//! [`serde_json::to_string`][to_string]. There is also +//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec` and +//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write` +//! such as a File or a TCP stream. +//! +//! ```rust +//! extern crate serde; +//! extern crate serde_json; +//! +//! #[macro_use] +//! extern crate serde_derive; +//! +//! use serde_json::Error; +//! +//! #[derive(Serialize, Deserialize)] +//! struct Address { +//! street: String, +//! city: String, +//! } +//! +//! fn print_an_address() -> Result<(), Error> { +//! // Some data structure. +//! let address = Address { +//! street: "10 Downing Street".to_owned(), +//! city: "London".to_owned(), +//! }; +//! +//! // Serialize it to a JSON string. +//! let j = serde_json::to_string(&address)?; +//! +//! // Print, write to a file, or send to an HTTP server. +//! println!("{}", j); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # print_an_address().unwrap(); +//! # } +//! ``` +//! +//! Any type that implements Serde's `Serialize` trait can be serialized this +//! way. This includes built-in Rust standard library types like `Vec` and +//! `HashMap`, as well as any structs or enums annotated with +//! `#[derive(Serialize)]`. +//! +//! # No-std support +//! +//! This crate currently requires the Rust standard library. For JSON support in +//! Serde without a standard library, please see the [`serde-json-core`] crate. +//! +//! [value]: https://docs.serde.rs/serde_json/value/enum.Value.html +//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html +//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html +//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html +//! [to_string]: https://docs.serde.rs/serde_json/ser/fn.to_string.html +//! [to_vec]: https://docs.serde.rs/serde_json/ser/fn.to_vec.html +//! [to_writer]: https://docs.serde.rs/serde_json/ser/fn.to_writer.html +//! [macro]: https://docs.serde.rs/serde_json/macro.json.html +//! [`serde-json-core`]: https://japaric.github.io/serde-json-core/serde_json_core/ + +#![doc(html_root_url = "https://docs.rs/serde_json/1.0.26")] +#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] +// Whitelisted clippy lints +#![cfg_attr( + feature = "cargo-clippy", + allow(doc_markdown, needless_pass_by_value) +)] +// Whitelisted clippy_pedantic lints +#![cfg_attr(feature = "cargo-clippy", allow( +// Deserializer::from_str, into_iter + should_implement_trait, +// integer and float ser/de requires these sorts of casts + cast_possible_truncation, + cast_possible_wrap, + cast_precision_loss, + cast_sign_loss, +// string ser/de uses indexing and slicing + indexing_slicing, +// things are often more readable this way + cast_lossless, + shadow_reuse, + shadow_unrelated, + single_match_else, + stutter, + use_self, +// not practical + missing_docs_in_private_items, + similar_names, +// we support older compilers + redundant_field_names, +))] +#![deny(missing_docs)] + +#[macro_use] +extern crate serde; +extern crate ryu; +#[cfg(feature = "preserve_order")] +extern crate indexmap; +extern crate itoa; + +#[doc(inline)] +pub use self::de::{from_reader, from_slice, from_str, Deserializer, StreamDeserializer}; +#[doc(inline)] +pub use self::error::{Error, Result}; +#[doc(inline)] +pub use self::ser::{ + to_string, to_string_pretty, to_vec, to_vec_pretty, to_writer, to_writer_pretty, Serializer, +}; +#[doc(inline)] +pub use self::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! try { + ($e:expr) => { + match $e { + ::std::result::Result::Ok(val) => val, + ::std::result::Result::Err(err) => return ::std::result::Result::Err(err), + } + }; +} + +#[macro_use] +mod macros; + +pub mod de; +pub mod error; +pub mod map; +pub mod ser; +pub mod value; + +mod iter; +mod number; +mod read; diff --git a/third_party/rust/serde_json/src/macros.rs b/third_party/rust/serde_json/src/macros.rs new file mode 100644 index 000000000000..ee163fc341f2 --- /dev/null +++ b/third_party/rust/serde_json/src/macros.rs @@ -0,0 +1,309 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Construct a `serde_json::Value` from a JSON literal. +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_json; +/// # +/// # fn main() { +/// let value = json!({ +/// "code": 200, +/// "success": true, +/// "payload": { +/// "features": [ +/// "serde", +/// "json" +/// ] +/// } +/// }); +/// # } +/// ``` +/// +/// Variables or expressions can be interpolated into the JSON literal. Any type +/// interpolated into an array element or object value must implement Serde's +/// `Serialize` trait, while any type interpolated into a object key must +/// implement `Into`. If the `Serialize` implementation of the +/// interpolated type decides to fail, or if the interpolated type contains a +/// map with non-string keys, the `json!` macro will panic. +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_json; +/// # +/// # fn main() { +/// 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. +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_json; +/// # +/// # fn main() { +/// let value = json!([ +/// "notice", +/// "the", +/// "trailing", +/// "comma -->", +/// ]); +/// # } +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! json { + // Hide distracting implementation details from the generated rustdoc. + ($($json:tt)+) => { + json_internal!($($json)+) + }; +} + +// Rocket relies on this because they export their own `json!` with a different +// doc comment than ours, and various Rust bugs prevent them from calling our +// `json!` from their `json!` so they call `json_internal!` directly. Check with +// @SergioBenitez before making breaking changes to this macro. +// +// Changes are fine as long as `json_internal!` does not call any new helper +// macros and can still be invoked as `json_internal!($($json)+)`. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! json_internal { + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an array [...]. Produces a vec![...] + // of the elements. + // + // Must be invoked as: json_internal!(@array [] $($tt)*) + ////////////////////////////////////////////////////////////////////////// + + // Done with trailing comma. + (@array [$($elems:expr,)*]) => { + json_internal_vec![$($elems,)*] + }; + + // Done without trailing comma. + (@array [$($elems:expr),*]) => { + json_internal_vec![$($elems),*] + }; + + // Next element is `null`. + (@array [$($elems:expr,)*] null $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*) + }; + + // Next element is `true`. + (@array [$($elems:expr,)*] true $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*) + }; + + // Next element is `false`. + (@array [$($elems:expr,)*] false $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*) + }; + + // Next element is an array. + (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*) + }; + + // Next element is a map. + (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*) + }; + + // Next element is an expression followed by comma. + (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { + json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*) + }; + + // Last element is an expression with no trailing comma. + (@array [$($elems:expr,)*] $last:expr) => { + json_internal!(@array [$($elems,)* json_internal!($last)]) + }; + + // Comma after the most recent element. + (@array [$($elems:expr),*] , $($rest:tt)*) => { + json_internal!(@array [$($elems,)*] $($rest)*) + }; + + // Unexpected token after most recent element. + (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { + json_unexpected!($unexpected) + }; + + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an object {...}. Each entry is + // inserted into the given map variable. + // + // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*)) + // + // We require two copies of the input tokens so that we can match on one + // copy and trigger errors on the other copy. + ////////////////////////////////////////////////////////////////////////// + + // Done. + (@object $object:ident () () ()) => {}; + + // Insert the current entry followed by trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { + let _ = $object.insert(($($key)+).into(), $value); + json_internal!(@object $object () ($($rest)*) ($($rest)*)); + }; + + // Current entry followed by unexpected token. + (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { + json_unexpected!($unexpected); + }; + + // Insert the last entry without trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr)) => { + let _ = $object.insert(($($key)+).into(), $value); + }; + + // Next value is `null`. + (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*); + }; + + // Next value is `true`. + (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*); + }; + + // Next value is `false`. + (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*); + }; + + // Next value is an array. + (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*); + }; + + // Next value is a map. + (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*); + }; + + // Next value is an expression followed by comma. + (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*); + }; + + // Last value is an expression with no trailing comma. + (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { + json_internal!(@object $object [$($key)+] (json_internal!($value))); + }; + + // Missing value for last entry. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { + // "unexpected end of macro invocation" + json_internal!(); + }; + + // Missing colon and value for last entry. Trigger a reasonable error + // message. + (@object $object:ident ($($key:tt)+) () $copy:tt) => { + // "unexpected end of macro invocation" + json_internal!(); + }; + + // Misplaced colon. Trigger a reasonable error message. + (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `:`". + json_unexpected!($colon); + }; + + // Found a comma inside a key. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `,`". + json_unexpected!($comma); + }; + + // Key is fully parenthesized. This avoids clippy double_parens false + // positives because the parenthesization may be necessary here. + (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); + }; + + // Munch a token into the current key. + (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { + json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); + }; + + ////////////////////////////////////////////////////////////////////////// + // The main implementation. + // + // Must be invoked as: json_internal!($($json)+) + ////////////////////////////////////////////////////////////////////////// + + (null) => { + $crate::Value::Null + }; + + (true) => { + $crate::Value::Bool(true) + }; + + (false) => { + $crate::Value::Bool(false) + }; + + ([]) => { + $crate::Value::Array(json_internal_vec![]) + }; + + ([ $($tt:tt)+ ]) => { + $crate::Value::Array(json_internal!(@array [] $($tt)+)) + }; + + ({}) => { + $crate::Value::Object($crate::Map::new()) + }; + + ({ $($tt:tt)+ }) => { + $crate::Value::Object({ + let mut object = $crate::Map::new(); + json_internal!(@object object () ($($tt)+) ($($tt)+)); + object + }) + }; + + // Any Serialize type: numbers, strings, struct literals, variables etc. + // Must be below every other rule. + ($other:expr) => { + $crate::to_value(&$other).unwrap() + }; +} + +// The json_internal macro above cannot invoke vec directly because it uses +// local_inner_macros. A vec invocation there would resolve to $crate::vec. +// Instead invoke vec here outside of local_inner_macros. +#[macro_export] +#[doc(hidden)] +macro_rules! json_internal_vec { + ($($content:tt)*) => { + vec![$($content)*] + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! json_unexpected { + () => {}; +} diff --git a/third_party/rust/serde_json/src/map.rs b/third_party/rust/serde_json/src/map.rs new file mode 100644 index 000000000000..dd28c757d746 --- /dev/null +++ b/third_party/rust/serde_json/src/map.rs @@ -0,0 +1,852 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! 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 serde::{de, ser}; +use std::borrow::Borrow; +use std::fmt::{self, Debug}; +use std::hash::Hash; +use std::iter::FromIterator; +use std::ops; +use value::Value; + +#[cfg(not(feature = "preserve_order"))] +use std::collections::{btree_map, BTreeMap}; + +#[cfg(feature = "preserve_order")] +use indexmap::{self, IndexMap}; + +/// Represents a JSON key/value type. +pub struct Map { + map: MapImpl, +} + +#[cfg(not(feature = "preserve_order"))] +type MapImpl = BTreeMap; +#[cfg(feature = "preserve_order")] +type MapImpl = IndexMap; + +impl Map { + /// Makes a new empty Map. + #[inline] + pub fn new() -> Self { + Map { + map: MapImpl::new(), + } + } + + #[cfg(not(feature = "preserve_order"))] + /// Makes a new empty Map with the given initial capacity. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + // does not support with_capacity + let _ = capacity; + Map { + map: BTreeMap::new(), + } + } + + #[cfg(feature = "preserve_order")] + /// Makes a new empty Map with the given initial capacity. + #[inline] + pub fn with_capacity(capacity: usize) -> Self { + Map { + map: IndexMap::with_capacity(capacity), + } + } + + /// Clears the map, removing all values. + #[inline] + pub fn clear(&mut self) { + self.map.clear() + } + + /// Returns a reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn get(&self, key: &Q) -> Option<&Value> + where + String: Borrow, + Q: Ord + Eq + Hash, + { + self.map.get(key) + } + + /// Returns true if the map contains a value for the specified key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn contains_key(&self, key: &Q) -> bool + where + String: Borrow, + Q: Ord + Eq + Hash, + { + self.map.contains_key(key) + } + + /// Returns a mutable reference to the value corresponding to the key. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn get_mut(&mut self, key: &Q) -> Option<&mut Value> + where + String: Borrow, + Q: Ord + Eq + Hash, + { + self.map.get_mut(key) + } + + /// Inserts a key-value pair into the map. + /// + /// If the map did not have this key present, `None` is returned. + /// + /// If the map did have this key present, the value is updated, and the old + /// value is returned. + #[inline] + pub fn insert(&mut self, k: String, v: Value) -> Option { + self.map.insert(k, v) + } + + /// Removes a key from the map, returning the value at the key if the key + /// was previously in the map. + /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + #[inline] + pub fn remove(&mut self, key: &Q) -> Option + where + String: Borrow, + Q: Ord + Eq + Hash, + { + self.map.remove(key) + } + + /// Gets the given key's corresponding entry in the map for in-place + /// manipulation. + pub fn entry(&mut self, key: S) -> Entry + where + S: Into, + { + #[cfg(feature = "preserve_order")] + use indexmap::map::Entry as EntryImpl; + #[cfg(not(feature = "preserve_order"))] + use std::collections::btree_map::Entry as EntryImpl; + + match self.map.entry(key.into()) { + EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant: vacant }), + EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied: occupied }), + } + } + + /// Returns the number of elements in the map. + #[inline] + pub fn len(&self) -> usize { + self.map.len() + } + + /// Returns true if the map contains no elements. + #[inline] + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// Gets an iterator over the entries of the map. + #[inline] + pub fn iter(&self) -> Iter { + Iter { + iter: self.map.iter(), + } + } + + /// Gets a mutable iterator over the entries of the map. + #[inline] + pub fn iter_mut(&mut self) -> IterMut { + IterMut { + iter: self.map.iter_mut(), + } + } + + /// Gets an iterator over the keys of the map. + #[inline] + pub fn keys(&self) -> Keys { + Keys { + iter: self.map.keys(), + } + } + + /// Gets an iterator over the values of the map. + #[inline] + pub fn values(&self) -> Values { + Values { + iter: self.map.values(), + } + } + + /// Gets an iterator over mutable values of the map. + #[inline] + pub fn values_mut(&mut self) -> ValuesMut { + ValuesMut { + iter: self.map.values_mut(), + } + } +} + +impl Default for Map { + #[inline] + fn default() -> Self { + Map { + map: MapImpl::new(), + } + } +} + +impl Clone for Map { + #[inline] + fn clone(&self) -> Self { + Map { + map: self.map.clone(), + } + } +} + +impl PartialEq for Map { + #[inline] + fn eq(&self, other: &Self) -> bool { + if cfg!(feature = "preserve_order") { + if self.len() != other.len() { + return false; + } + + self.iter() + .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) + } else { + self.map.eq(&other.map) + } + } +} + +/// Access an element of this map. Panics if the given key is not present in the +/// map. +/// +/// ```rust +/// # use serde_json::Value; +/// # +/// # let val = &Value::String("".to_owned()); +/// # let _ = +/// match *val { +/// Value::String(ref s) => Some(s.as_str()), +/// Value::Array(ref arr) => arr[0].as_str(), +/// Value::Object(ref map) => map["type"].as_str(), +/// _ => None, +/// } +/// # ; +/// ``` +impl<'a, Q: ?Sized> ops::Index<&'a Q> for Map +where + String: Borrow, + Q: 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. +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_json; +/// # +/// # fn main() { +/// # let mut map = serde_json::Map::new(); +/// # map.insert("key".to_owned(), serde_json::Value::Null); +/// # +/// map["key"] = json!("value"); +/// # } +/// ``` +impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map +where + String: Borrow, + Q: Ord + Eq + Hash, +{ + fn index_mut(&mut self, index: &Q) -> &mut Value { + self.map.get_mut(index).expect("no entry found for key") + } +} + +impl Debug for Map { + #[inline] + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + self.map.fmt(formatter) + } +} + +impl ser::Serialize for Map { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + use serde::ser::SerializeMap; + let mut map = try!(serializer.serialize_map(Some(self.len()))); + for (k, v) in self { + try!(map.serialize_key(k)); + try!(map.serialize_value(v)); + } + map.end() + } +} + +impl<'de> de::Deserialize<'de> for Map { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = Map; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map") + } + + #[inline] + fn visit_unit(self) -> Result + where + E: de::Error, + { + Ok(Map::new()) + } + + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where + V: de::MapAccess<'de>, + { + let mut values = Map::new(); + + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(values) + } + } + + deserializer.deserialize_map(Visitor) + } +} + +impl FromIterator<(String, Value)> for Map { + fn from_iter(iter: T) -> Self + where + T: IntoIterator, + { + Map { + map: FromIterator::from_iter(iter), + } + } +} + +impl Extend<(String, Value)> for Map { + fn extend(&mut self, iter: T) + where + T: IntoIterator, + { + self.map.extend(iter); + } +} + +macro_rules! delegate_iterator { + (($name:ident $($generics:tt)*) => $item:ty) => { + impl $($generics)* Iterator for $name $($generics)* { + type Item = $item; + #[inline] + fn next(&mut self) -> Option { + self.iter.next() + } + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + } + + impl $($generics)* DoubleEndedIterator for $name $($generics)* { + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back() + } + } + + impl $($generics)* ExactSizeIterator for $name $($generics)* { + #[inline] + fn len(&self) -> usize { + self.iter.len() + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +/// 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 + /// + /// ```rust + /// let mut map = serde_json::Map::new(); + /// assert_eq!(map.entry("serde").key(), &"serde"); + /// ``` + pub fn key(&self) -> &String { + match *self { + Entry::Vacant(ref e) => e.key(), + Entry::Occupied(ref e) => e.key(), + } + } + + /// Ensures a value is in the entry by inserting the default if empty, and + /// returns a mutable reference to the value in the entry. + /// + /// # Examples + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut map = serde_json::Map::new(); + /// map.entry("serde").or_insert_with(|| json!("hoho")); + /// + /// assert_eq!(map["serde"], "hoho".to_owned()); + /// # } + /// ``` + pub fn or_insert_with(self, default: F) -> &'a mut Value + where + F: FnOnce() -> Value, + { + match self { + Entry::Vacant(entry) => entry.insert(default()), + Entry::Occupied(entry) => entry.into_mut(), + } + } +} + +impl<'a> VacantEntry<'a> { + /// Gets a reference to the key that would be used when inserting a value + /// through the VacantEntry. + /// + /// # Examples + /// + /// ```rust + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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 { + self.occupied.remove() + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a Map { + type Item = (&'a String, &'a Value); + type IntoIter = Iter<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + Iter { + iter: self.map.iter(), + } + } +} + +/// An iterator over a serde_json::Map's entries. +pub struct Iter<'a> { + iter: IterImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterImpl<'a> = btree_map::Iter<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; + +delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> IntoIterator for &'a mut Map { + type Item = (&'a String, &'a mut Value); + type IntoIter = IterMut<'a>; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IterMut { + iter: self.map.iter_mut(), + } + } +} + +/// A mutable iterator over a serde_json::Map's entries. +pub struct IterMut<'a> { + iter: IterMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; + +delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); + +////////////////////////////////////////////////////////////////////////////// + +impl IntoIterator for Map { + type Item = (String, Value); + type IntoIter = IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + IntoIter { + iter: self.map.into_iter(), + } + } +} + +/// An owning iterator over a serde_json::Map's entries. +pub struct IntoIter { + iter: IntoIterImpl, +} + +#[cfg(not(feature = "preserve_order"))] +type IntoIterImpl = btree_map::IntoIter; +#[cfg(feature = "preserve_order")] +type IntoIterImpl = indexmap::map::IntoIter; + +delegate_iterator!((IntoIter) => (String, Value)); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's keys. +pub struct Keys<'a> { + iter: KeysImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; + +delegate_iterator!((Keys<'a>) => &'a String); + +////////////////////////////////////////////////////////////////////////////// + +/// An iterator over a serde_json::Map's values. +pub struct Values<'a> { + iter: ValuesImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; + +delegate_iterator!((Values<'a>) => &'a Value); + +////////////////////////////////////////////////////////////////////////////// + +/// A mutable iterator over a serde_json::Map's values. +pub struct ValuesMut<'a> { + iter: ValuesMutImpl<'a>, +} + +#[cfg(not(feature = "preserve_order"))] +type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; +#[cfg(feature = "preserve_order")] +type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; + +delegate_iterator!((ValuesMut<'a>) => &'a mut Value); diff --git a/third_party/rust/serde_json/src/number.rs b/third_party/rust/serde_json/src/number.rs new file mode 100644 index 000000000000..30f1552524fa --- /dev/null +++ b/third_party/rust/serde_json/src/number.rs @@ -0,0 +1,770 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use error::Error; +use serde::de::{self, Unexpected, Visitor}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt::{self, Debug, Display}; + +#[cfg(feature = "arbitrary_precision")] +use ryu; +#[cfg(feature = "arbitrary_precision")] +use itoa; +#[cfg(feature = "arbitrary_precision")] +use serde::de::{IntoDeserializer, MapAccess}; + +use de::ParserNumber; + +#[cfg(feature = "arbitrary_precision")] +use error::ErrorCode; + +#[cfg(feature = "arbitrary_precision")] +/// Not public API. Should be pub(crate). +#[doc(hidden)] +pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$__serde_private_number"; + +#[cfg(feature = "arbitrary_precision")] +/// Not public API. Should be pub(crate). +#[doc(hidden)] +pub const SERDE_STRUCT_NAME: &'static str = "$__serde_private_Number"; + +/// Represents a JSON number, whether integer or floating point. +#[derive(Clone, PartialEq)] +pub struct Number { + n: N, +} + +#[cfg(not(feature = "arbitrary_precision"))] +#[derive(Copy, Clone, PartialEq)] +enum N { + PosInt(u64), + /// Always less than zero. + NegInt(i64), + /// Always finite. + Float(f64), +} + +#[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. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// 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. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// # } + /// ``` + #[inline] + pub fn is_f64(&self) -> bool { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::Float(_) => true, + N::PosInt(_) | N::NegInt(_) => false, + } + #[cfg(feature = "arbitrary_precision")] + { + for c in self.n.chars() { + if c == '.' || c == 'e' || c == 'E' { + return self.n.parse::().ok().map_or(false, |f| f.is_finite()); + } + } + false + } + } + + /// If the `Number` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// # } + /// ``` + #[inline] + pub fn as_i64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => if n <= i64::max_value() as u64 { + Some(n as i64) + } else { + None + }, + N::NegInt(n) => Some(n), + N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// If the `Number` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// # } + /// ``` + #[inline] + pub fn as_u64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n), + N::NegInt(_) | N::Float(_) => None, + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// Represents the number as f64 if possible. Returns None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// # } + /// ``` + #[inline] + pub fn as_f64(&self) -> Option { + #[cfg(not(feature = "arbitrary_precision"))] + match self.n { + N::PosInt(n) => Some(n as f64), + N::NegInt(n) => Some(n as f64), + N::Float(n) => Some(n), + } + #[cfg(feature = "arbitrary_precision")] + self.n.parse().ok() + } + + /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON + /// numbers. + /// + /// ```rust + /// # use std::f64; + /// # + /// # use serde_json::Number; + /// # + /// assert!(Number::from_f64(256.0).is_some()); + /// + /// assert!(Number::from_f64(f64::NAN).is_none()); + /// ``` + #[inline] + pub fn from_f64(f: f64) -> Option { + if f.is_finite() { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + ryu::Buffer::new().format(f).to_owned() + } + }; + Some(Number { n: n }) + } else { + None + } + } + + #[cfg(feature = "arbitrary_precision")] + /// Not public API. Only tests use this. + #[doc(hidden)] + #[inline] + pub fn from_string_unchecked(n: String) -> Self { + Number { n: n } + } +} + +impl fmt::Display for Number { + #[cfg(not(feature = "arbitrary_precision"))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self.n { + N::PosInt(u) => Display::fmt(&u, formatter), + N::NegInt(i) => Display::fmt(&i, formatter), + N::Float(f) => Display::fmt(&f, formatter), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + Display::fmt(&self.n, formatter) + } +} + +impl Debug for Number { + #[cfg(not(feature = "arbitrary_precision"))] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + let mut debug = formatter.debug_tuple("Number"); + match self.n { + N::PosInt(i) => { + debug.field(&i); + } + N::NegInt(i) => { + debug.field(&i); + } + N::Float(f) => { + debug.field(&f); + } + } + debug.finish() + } + + #[cfg(feature = "arbitrary_precision")] + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "Number({})", &self.n) + } +} + +impl Serialize for Number { + #[cfg(not(feature = "arbitrary_precision"))] + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self.n { + N::PosInt(u) => serializer.serialize_u64(u), + N::NegInt(i) => serializer.serialize_i64(i), + N::Float(f) => serializer.serialize_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use serde::ser::SerializeStruct; + + let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?; + s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.n)?; + s.end() + } +} + +impl<'de> Deserialize<'de> for Number { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct NumberVisitor; + + impl<'de> Visitor<'de> for NumberVisitor { + type Value = Number; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a JSON number") + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(value.into()) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(value.into()) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result + where + E: de::Error, + { + Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number")) + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn visit_map(self, mut visitor: V) -> Result + where + V: de::MapAccess<'de>, + { + let value = visitor.next_key::()?; + if value.is_none() { + return Err(de::Error::invalid_type(Unexpected::Map, &self)); + } + let v: NumberFromString = visitor.next_value()?; + Ok(v.value) + } + } + + deserializer.deserialize_any(NumberVisitor) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberKey; + +#[cfg(feature = "arbitrary_precision")] +impl<'de> de::Deserialize<'de> for NumberKey { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct FieldVisitor; + + impl<'de> de::Visitor<'de> for FieldVisitor { + type Value = (); + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a valid number field") + } + + fn visit_str(self, s: &str) -> Result<(), E> + where + E: de::Error, + { + if s == SERDE_STRUCT_FIELD_NAME { + Ok(()) + } else { + Err(de::Error::custom("expected field with custom name")) + } + } + } + + deserializer.deserialize_identifier(FieldVisitor)?; + Ok(NumberKey) + } +} + +#[cfg(feature = "arbitrary_precision")] +pub struct NumberFromString { + pub value: Number, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> de::Deserialize<'de> for NumberFromString { + fn deserialize(deserializer: D) -> Result + where + D: de::Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = NumberFromString; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string containing a number") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + let n = try!(s.parse().map_err(de::Error::custom)); + Ok(NumberFromString { value: n }) + } + } + + deserializer.deserialize_str(Visitor) + } +} + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +macro_rules! deserialize_any { + (@expand [$($num_string:tt)*]) => { + #[cfg(not(feature = "arbitrary_precision"))] + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.n { + N::PosInt(u) => visitor.visit_u64(u), + N::NegInt(i) => visitor.visit_i64(i), + N::Float(f) => visitor.visit_f64(f), + } + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where V: Visitor<'de> + { + if let Some(u) = self.as_u64() { + return visitor.visit_u64(u); + } else if let Some(i) = self.as_i64() { + return visitor.visit_i64(i); + } else if let Some(f) = self.as_f64() { + if f.to_string() == self.n { + return visitor.visit_f64(f); + } + } + + visitor.visit_map(NumberDeserializer { + number: Some(self.$($num_string)*), + }) + } + }; + + (owned) => { + deserialize_any!(@expand [n]); + }; + + (ref) => { + deserialize_any!(@expand [n.clone()]); + }; +} + +macro_rules! deserialize_number { + ($deserialize:ident => $visit:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $deserialize(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_any(visitor) + } + + #[cfg(feature = "arbitrary_precision")] + fn $deserialize(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.$visit(self.n.parse().map_err(|_| invalid_number())?) + } + } +} + +impl<'de> Deserializer<'de> for Number { + type Error = Error; + + deserialize_any!(owned); + + deserialize_number!(deserialize_i8 => visit_i8); + deserialize_number!(deserialize_i16 => visit_i16); + deserialize_number!(deserialize_i32 => visit_i32); + deserialize_number!(deserialize_i64 => visit_i64); + deserialize_number!(deserialize_u8 => visit_u8); + deserialize_number!(deserialize_u16 => visit_u16); + deserialize_number!(deserialize_u32 => visit_u32); + deserialize_number!(deserialize_u64 => visit_u64); + deserialize_number!(deserialize_f32 => visit_f32); + deserialize_number!(deserialize_f64 => visit_f64); + + serde_if_integer128! { + deserialize_number!(deserialize_i128 => visit_i128); + deserialize_number!(deserialize_u128 => visit_u128); + } + + forward_to_deserialize_any! { + bool char str string bytes byte_buf option unit unit_struct + newtype_struct seq tuple tuple_struct map struct enum identifier + ignored_any + } +} + +impl<'de, 'a> Deserializer<'de> for &'a Number { + type Error = Error; + + deserialize_any!(ref); + + deserialize_number!(deserialize_i8 => visit_i8); + deserialize_number!(deserialize_i16 => visit_i16); + deserialize_number!(deserialize_i32 => visit_i32); + deserialize_number!(deserialize_i64 => visit_i64); + deserialize_number!(deserialize_u8 => visit_u8); + deserialize_number!(deserialize_u16 => visit_u16); + deserialize_number!(deserialize_u32 => visit_u32); + deserialize_number!(deserialize_u64 => visit_u64); + deserialize_number!(deserialize_f32 => visit_f32); + deserialize_number!(deserialize_f64 => visit_f64); + + serde_if_integer128! { + deserialize_number!(deserialize_i128 => visit_i128); + deserialize_number!(deserialize_u128 => visit_u128); + } + + forward_to_deserialize_any! { + bool char str string bytes byte_buf option unit unit_struct + newtype_struct seq tuple tuple_struct map struct enum identifier + ignored_any + } +} + +#[cfg(feature = "arbitrary_precision")] +// Not public API. Should be pub(crate). +#[doc(hidden)] +pub struct NumberDeserializer { + pub number: Option, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'de> MapAccess<'de> for NumberDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: de::DeserializeSeed<'de>, + { + if self.number.is_none() { + return Ok(None); + } + seed.deserialize(NumberFieldDeserializer).map(Some) + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + seed.deserialize(self.number.take().unwrap().into_deserializer()) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberFieldDeserializer; + +#[cfg(feature = "arbitrary_precision")] +impl<'de> Deserializer<'de> for NumberFieldDeserializer { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_borrowed_str(SERDE_STRUCT_FIELD_NAME) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq + bytes byte_buf map struct option unit newtype_struct ignored_any + unit_struct tuple_struct tuple enum identifier + } +} + +impl From for Number { + fn from(value: ParserNumber) -> Self { + let n = match value { + ParserNumber::F64(f) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::Float(f) + } + #[cfg(feature = "arbitrary_precision")] + { + f.to_string() + } + } + ParserNumber::U64(u) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::PosInt(u) + } + #[cfg(feature = "arbitrary_precision")] + { + u.to_string() + } + } + ParserNumber::I64(i) => { + #[cfg(not(feature = "arbitrary_precision"))] + { + N::NegInt(i) + } + #[cfg(feature = "arbitrary_precision")] + { + i.to_string() + } + } + #[cfg(feature = "arbitrary_precision")] + ParserNumber::String(s) => s, + }; + Number { n: n } + } +} + +macro_rules! impl_from_unsigned { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(u: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { N::PosInt(u as u64) } + #[cfg(feature = "arbitrary_precision")] + { + let mut buf = Vec::new(); + itoa::write(&mut buf, u).unwrap(); + String::from_utf8(buf).unwrap() + } + }; + Number { n: n } + } + } + )* + }; +} + +macro_rules! impl_from_signed { + ( + $($ty:ty),* + ) => { + $( + impl From<$ty> for Number { + #[inline] + fn from(i: $ty) -> Self { + let n = { + #[cfg(not(feature = "arbitrary_precision"))] + { + if i < 0 { + N::NegInt(i as i64) + } else { + N::PosInt(i as u64) + } + } + #[cfg(feature = "arbitrary_precision")] + { + let mut buf = Vec::new(); + itoa::write(&mut buf, i).unwrap(); + String::from_utf8(buf).unwrap() + } + }; + Number { n: n } + } + } + )* + }; +} + +impl_from_unsigned!(u8, u16, u32, u64, usize); +impl_from_signed!(i8, i16, i32, i64, isize); + +impl Number { + #[cfg(not(feature = "arbitrary_precision"))] + // Not public API. Should be pub(crate). + #[doc(hidden)] + #[cold] + pub 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")] + // Not public API. Should be pub(crate). + #[doc(hidden)] + #[cold] + pub fn unexpected(&self) -> Unexpected { + Unexpected::Other("number") + } +} diff --git a/third_party/rust/serde_json/src/read.rs b/third_party/rust/serde_json/src/read.rs new file mode 100644 index 000000000000..f2cc9f93b461 --- /dev/null +++ b/third_party/rust/serde_json/src/read.rs @@ -0,0 +1,677 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ops::Deref; +use std::{char, cmp, io, str}; + +use iter::LineColIterator; + +use super::error::{Error, ErrorCode, Result}; + +/// Trait used by the deserializer for iterating over input. This is manually +/// "specialized" for iterating over &[u8]. Once feature(specialization) is +/// stable we can use actual specialization. +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +pub trait Read<'de>: private::Sealed { + #[doc(hidden)] + fn next(&mut self) -> io::Result>; + #[doc(hidden)] + fn peek(&mut self) -> io::Result>; + + /// Only valid after a call to peek(). Discards the peeked byte. + #[doc(hidden)] + fn discard(&mut self); + + /// Position of the most recent call to next(). + /// + /// The most recent call was probably next() and not peek(), but this method + /// should try to return a sensible result if the most recent call was + /// actually peek() because we don't always know. + /// + /// Only called in case of an error, so performance is not important. + #[doc(hidden)] + fn position(&self) -> Position; + + /// Position of the most recent call to peek(). + /// + /// The most recent call was probably peek() and not next(), but this method + /// should try to return a sensible result if the most recent call was + /// actually next() because we don't always know. + /// + /// Only called in case of an error, so performance is not important. + #[doc(hidden)] + fn peek_position(&self) -> Position; + + /// Offset from the beginning of the input to the next byte that would be + /// returned by next() or peek(). + #[doc(hidden)] + fn byte_offset(&self) -> usize; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark using the given scratch space if + /// necessary. The scratch space is initially empty. + #[doc(hidden)] + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark using the given scratch space if + /// necessary. The scratch space is initially empty. + /// + /// This function returns the raw bytes in the string with escape sequences + /// expanded but without performing unicode validation. + #[doc(hidden)] + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result>; + + /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped + /// string until the next quotation mark but discards the data. + #[doc(hidden)] + fn ignore_str(&mut self) -> Result<()>; +} + +pub struct Position { + pub line: usize, + pub column: usize, +} + +pub enum Reference<'b, 'c, T: ?Sized + 'static> { + Borrowed(&'b T), + Copied(&'c T), +} + +impl<'b, 'c, T: ?Sized + 'static> Deref for Reference<'b, 'c, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + match *self { + Reference::Borrowed(b) => b, + Reference::Copied(c) => c, + } + } +} + +/// JSON input source that reads from a std::io input stream. +pub struct IoRead +where + R: io::Read, +{ + iter: LineColIterator>, + /// Temporary storage of peeked byte. + ch: Option, +} + +/// JSON input source that reads from a slice of bytes. +// +// This is more efficient than other iterators because peek() can be read-only +// and we can compute line/col position only if an error happens. +pub struct SliceRead<'a> { + slice: &'a [u8], + /// Index of the *next* byte that will be returned by next() or peek(). + index: usize, +} + +/// JSON input source that reads from a UTF-8 string. +// +// Able to elide UTF-8 checks by assuming that the input is valid UTF-8. +pub struct StrRead<'a> { + delegate: SliceRead<'a>, +} + +// Prevent users from implementing the Read trait. +mod private { + pub trait Sealed {} +} + +////////////////////////////////////////////////////////////////////////////// + +impl IoRead +where + R: io::Read, +{ + /// Create a JSON input source to read from a std::io input stream. + pub fn new(reader: R) -> Self { + IoRead { + iter: LineColIterator::new(reader.bytes()), + ch: None, + } + } +} + +impl private::Sealed for IoRead where R: io::Read {} + +impl IoRead +where + R: io::Read, +{ + fn parse_str_bytes<'s, T, F>( + &'s mut self, + scratch: &'s mut Vec, + validate: bool, + result: F, + ) -> Result + where + T: 's, + F: FnOnce(&'s Self, &'s [u8]) -> Result, + { + loop { + let ch = try!(next_or_eof(self)); + if !ESCAPE[ch as usize] { + scratch.push(ch); + continue; + } + match ch { + b'"' => { + return result(self, scratch); + } + b'\\' => { + try!(parse_escape(self, scratch)); + } + _ => { + if validate { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + scratch.push(ch); + } + } + } + } +} + +impl<'de, R> Read<'de> for IoRead +where + R: io::Read, +{ + #[inline] + fn next(&mut self) -> io::Result> { + match self.ch.take() { + Some(ch) => Ok(Some(ch)), + None => match self.iter.next() { + Some(Err(err)) => Err(err), + Some(Ok(ch)) => Ok(Some(ch)), + None => Ok(None), + }, + } + } + + #[inline] + fn peek(&mut self) -> io::Result> { + match self.ch { + Some(ch) => Ok(Some(ch)), + None => match self.iter.next() { + Some(Err(err)) => Err(err), + Some(Ok(ch)) => { + self.ch = Some(ch); + Ok(self.ch) + } + None => Ok(None), + }, + } + } + + #[inline] + fn discard(&mut self) { + self.ch = None; + } + + fn position(&self) -> Position { + Position { + line: self.iter.line(), + column: self.iter.col(), + } + } + + fn peek_position(&self) -> Position { + // The LineColIterator updates its position during peek() so it has the + // right one here. + self.position() + } + + fn byte_offset(&self) -> usize { + match self.ch { + Some(_) => self.iter.byte_offset() - 1, + None => self.iter.byte_offset(), + } + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.parse_str_bytes(scratch, true, as_str) + .map(Reference::Copied) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) + .map(Reference::Copied) + } + + fn ignore_str(&mut self) -> Result<()> { + loop { + let ch = try!(next_or_eof(self)); + if !ESCAPE[ch as usize] { + continue; + } + match ch { + b'"' => { + return Ok(()); + } + b'\\' => { + try!(ignore_escape(self)); + } + _ => { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> SliceRead<'a> { + /// Create a JSON input source to read from a slice of bytes. + pub fn new(slice: &'a [u8]) -> Self { + SliceRead { + slice: slice, + index: 0, + } + } + + fn position_of_index(&self, i: usize) -> Position { + let mut position = Position { line: 1, column: 0 }; + for ch in &self.slice[..i] { + match *ch { + b'\n' => { + position.line += 1; + position.column = 0; + } + _ => { + position.column += 1; + } + } + } + position + } + + /// The big optimization here over IoRead is that if the string contains no + /// backslash escape sequences, the returned &str is a slice of the raw JSON + /// data so we avoid copying into the scratch space. + fn parse_str_bytes<'s, T: ?Sized, F>( + &'s mut self, + scratch: &'s mut Vec, + validate: bool, + result: F, + ) -> Result> + where + T: 's, + F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, + { + // Index of the first byte not yet copied into the scratch space. + let mut start = self.index; + + loop { + while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { + self.index += 1; + } + if self.index == self.slice.len() { + return error(self, ErrorCode::EofWhileParsingString); + } + match self.slice[self.index] { + b'"' => { + if scratch.is_empty() { + // Fast path: return a slice of the raw JSON without any + // copying. + let borrowed = &self.slice[start..self.index]; + self.index += 1; + return result(self, borrowed).map(Reference::Borrowed); + } else { + scratch.extend_from_slice(&self.slice[start..self.index]); + self.index += 1; + return result(self, scratch).map(Reference::Copied); + } + } + b'\\' => { + scratch.extend_from_slice(&self.slice[start..self.index]); + self.index += 1; + try!(parse_escape(self, scratch)); + start = self.index; + } + _ => { + if validate { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + self.index += 1; + } + } + } + } +} + +impl<'a> private::Sealed for SliceRead<'a> {} + +impl<'a> Read<'a> for SliceRead<'a> { + #[inline] + fn next(&mut self) -> io::Result> { + // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` + // is about 10% slower. + Ok(if self.index < self.slice.len() { + let ch = self.slice[self.index]; + self.index += 1; + Some(ch) + } else { + None + }) + } + + #[inline] + fn peek(&mut self) -> io::Result> { + // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower + // for some reason. + Ok(if self.index < self.slice.len() { + Some(self.slice[self.index]) + } else { + None + }) + } + + #[inline] + fn discard(&mut self) { + self.index += 1; + } + + fn position(&self) -> Position { + self.position_of_index(self.index) + } + + fn peek_position(&self) -> Position { + // Cap it at slice.len() just in case the most recent call was next() + // and it returned the last byte. + self.position_of_index(cmp::min(self.slice.len(), self.index + 1)) + } + + fn byte_offset(&self) -> usize { + self.index + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.parse_str_bytes(scratch, true, as_str) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) + } + + fn ignore_str(&mut self) -> Result<()> { + loop { + while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { + self.index += 1; + } + if self.index == self.slice.len() { + return error(self, ErrorCode::EofWhileParsingString); + } + match self.slice[self.index] { + b'"' => { + self.index += 1; + return Ok(()); + } + b'\\' => { + self.index += 1; + try!(ignore_escape(self)); + } + _ => { + return error(self, ErrorCode::ControlCharacterWhileParsingString); + } + } + } + } +} + +////////////////////////////////////////////////////////////////////////////// + +impl<'a> StrRead<'a> { + /// Create a JSON input source to read from a UTF-8 string. + pub fn new(s: &'a str) -> Self { + StrRead { + delegate: SliceRead::new(s.as_bytes()), + } + } +} + +impl<'a> private::Sealed for StrRead<'a> {} + +impl<'a> Read<'a> for StrRead<'a> { + #[inline] + fn next(&mut self) -> io::Result> { + self.delegate.next() + } + + #[inline] + fn peek(&mut self) -> io::Result> { + self.delegate.peek() + } + + #[inline] + fn discard(&mut self) { + self.delegate.discard(); + } + + fn position(&self) -> Position { + self.delegate.position() + } + + fn peek_position(&self) -> Position { + self.delegate.peek_position() + } + + fn byte_offset(&self) -> usize { + self.delegate.byte_offset() + } + + fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { + self.delegate.parse_str_bytes(scratch, true, |_, bytes| { + // The input is assumed to be valid UTF-8 and the \u-escapes are + // checked along the way, so don't need to check here. + Ok(unsafe { str::from_utf8_unchecked(bytes) }) + }) + } + + fn parse_str_raw<'s>( + &'s mut self, + scratch: &'s mut Vec, + ) -> Result> { + self.delegate.parse_str_raw(scratch) + } + + fn ignore_str(&mut self) -> Result<()> { + self.delegate.ignore_str() + } +} + +////////////////////////////////////////////////////////////////////////////// + +const CT: bool = true; // control character \x00...\x1F +const QU: bool = true; // quote \x22 +const BS: bool = true; // backslash \x5C +const O: bool = false; // allow unescaped + +// Lookup table of bytes that must be escaped. A value of true at index i means +// that byte i requires an escape sequence in the input. +#[cfg_attr(rustfmt, rustfmt_skip)] +static ESCAPE: [bool; 256] = [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 + CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 + O, O, QU, O, O, O, O, O, O, O, O, O, O, O, O, O, // 2 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 3 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 4 + O, O, O, O, O, O, O, O, O, O, O, O, BS, O, O, O, // 5 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 6 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 7 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 8 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 9 + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // A + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // B + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // C + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // D + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // E + O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // F +]; + +fn next_or_eof<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result { + match try!(read.next().map_err(Error::io)) { + Some(b) => Ok(b), + None => error(read, ErrorCode::EofWhileParsingString), + } +} + +fn error<'de, R: ?Sized + Read<'de>, T>(read: &R, reason: ErrorCode) -> Result { + let position = read.position(); + Err(Error::syntax(reason, position.line, position.column)) +} + +fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> { + str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint)) +} + +/// Parses a JSON escape sequence and appends it into the scratch space. Assumes +/// the previous byte read was a backslash. +fn parse_escape<'de, R: Read<'de>>(read: &mut R, scratch: &mut Vec) -> Result<()> { + let ch = try!(next_or_eof(read)); + + match ch { + b'"' => scratch.push(b'"'), + b'\\' => scratch.push(b'\\'), + b'/' => scratch.push(b'/'), + b'b' => scratch.push(b'\x08'), + b'f' => scratch.push(b'\x0c'), + b'n' => scratch.push(b'\n'), + b'r' => scratch.push(b'\r'), + b't' => scratch.push(b'\t'), + b'u' => { + let c = match try!(decode_hex_escape(read)) { + 0xDC00...0xDFFF => { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + // Non-BMP characters are encoded as a sequence of + // two hex escapes, representing UTF-16 surrogates. + n1 @ 0xD800...0xDBFF => { + if try!(next_or_eof(read)) != b'\\' { + return error(read, ErrorCode::UnexpectedEndOfHexEscape); + } + if try!(next_or_eof(read)) != b'u' { + return error(read, ErrorCode::UnexpectedEndOfHexEscape); + } + + let n2 = try!(decode_hex_escape(read)); + + if n2 < 0xDC00 || n2 > 0xDFFF { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; + + match char::from_u32(n) { + Some(c) => c, + None => { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + } + } + + n => match char::from_u32(n as u32) { + Some(c) => c, + None => { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + }, + }; + + scratch.extend_from_slice(c.encode_utf8(&mut [0_u8; 4]).as_bytes()); + } + _ => { + return error(read, ErrorCode::InvalidEscape); + } + } + + Ok(()) +} + +/// Parses a JSON escape sequence and discards the value. Assumes the previous +/// byte read was a backslash. +fn ignore_escape<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result<()> { + let ch = try!(next_or_eof(read)); + + match ch { + b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {} + b'u' => { + let n = match try!(decode_hex_escape(read)) { + 0xDC00...0xDFFF => { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + // Non-BMP characters are encoded as a sequence of + // two hex escapes, representing UTF-16 surrogates. + n1 @ 0xD800...0xDBFF => { + if try!(next_or_eof(read)) != b'\\' { + return error(read, ErrorCode::UnexpectedEndOfHexEscape); + } + if try!(next_or_eof(read)) != b'u' { + return error(read, ErrorCode::UnexpectedEndOfHexEscape); + } + + let n2 = try!(decode_hex_escape(read)); + + if n2 < 0xDC00 || n2 > 0xDFFF { + return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); + } + + (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000 + } + + n => n as u32, + }; + + if char::from_u32(n).is_none() { + return error(read, ErrorCode::InvalidUnicodeCodePoint); + } + } + _ => { + return error(read, ErrorCode::InvalidEscape); + } + } + + Ok(()) +} + +fn decode_hex_escape<'de, R: ?Sized + Read<'de>>(read: &mut R) -> Result { + let mut n = 0; + for _ in 0..4 { + n = match try!(next_or_eof(read)) { + c @ b'0'...b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)), + b'a' | b'A' => n * 16_u16 + 10_u16, + b'b' | b'B' => n * 16_u16 + 11_u16, + b'c' | b'C' => n * 16_u16 + 12_u16, + b'd' | b'D' => n * 16_u16 + 13_u16, + b'e' | b'E' => n * 16_u16 + 14_u16, + b'f' | b'F' => n * 16_u16 + 15_u16, + _ => { + return error(read, ErrorCode::InvalidEscape); + } + }; + } + Ok(n) +} diff --git a/third_party/rust/serde_json/src/ser.rs b/third_party/rust/serde_json/src/ser.rs new file mode 100644 index 000000000000..4214d0ce67f8 --- /dev/null +++ b/third_party/rust/serde_json/src/ser.rs @@ -0,0 +1,2096 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Serialize a Rust data structure into JSON data. + +use std::fmt; +use std::io; +use std::num::FpCategory; +use std::str; + +use super::error::{Error, ErrorCode, Result}; +use serde::ser::{self, Impossible}; + +use itoa; +use ryu; + +#[cfg(feature = "arbitrary_precision")] +use serde::Serialize; + +#[cfg(feature = "arbitrary_precision")] +use number::{SERDE_STRUCT_FIELD_NAME, SERDE_STRUCT_NAME}; + +/// A structure for serializing Rust values into JSON. +pub struct Serializer { + writer: W, + formatter: F, +} + +impl Serializer +where + W: io::Write, +{ + /// Creates a new JSON serializer. + #[inline] + pub fn new(writer: W) -> Self { + Serializer::with_formatter(writer, CompactFormatter) + } +} + +impl<'a, W> Serializer> +where + W: io::Write, +{ + /// Creates a new JSON pretty print serializer. + #[inline] + pub fn pretty(writer: W) -> Self { + Serializer::with_formatter(writer, PrettyFormatter::new()) + } +} + +impl Serializer +where + W: io::Write, + F: Formatter, +{ + /// Creates a new JSON visitor whose output will be written to the writer + /// specified. + #[inline] + pub fn with_formatter(writer: W, formatter: F) -> Self { + Serializer { + writer: writer, + formatter: formatter, + } + } + + /// Unwrap the `Writer` from the `Serializer`. + #[inline] + pub fn into_inner(self) -> W { + self.writer + } +} + +impl<'a, W, F> ser::Serializer for &'a mut Serializer +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + type SerializeSeq = Compound<'a, W, F>; + type SerializeTuple = Compound<'a, W, F>; + type SerializeTupleStruct = Compound<'a, W, F>; + type SerializeTupleVariant = Compound<'a, W, F>; + type SerializeMap = Compound<'a, W, F>; + type SerializeStruct = Compound<'a, W, F>; + type SerializeStructVariant = Compound<'a, W, F>; + + #[inline] + fn serialize_bool(self, value: bool) -> Result<()> { + try!( + self.formatter + .write_bool(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result<()> { + try!( + self.formatter + .write_i8(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result<()> { + try!( + self.formatter + .write_i16(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result<()> { + try!( + self.formatter + .write_i32(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_i64(self, value: i64) -> Result<()> { + try!( + self.formatter + .write_i64(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + serde_if_integer128! { + fn serialize_i128(self, value: i128) -> Result<()> { + self.formatter + .write_number_str(&mut self.writer, &value.to_string()) + .map_err(Error::io) + } + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result<()> { + try!( + self.formatter + .write_u8(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result<()> { + try!( + self.formatter + .write_u16(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result<()> { + try!( + self.formatter + .write_u32(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result<()> { + try!( + self.formatter + .write_u64(&mut self.writer, value) + .map_err(Error::io) + ); + Ok(()) + } + + serde_if_integer128! { + fn serialize_u128(self, value: u128) -> Result<()> { + self.formatter + .write_number_str(&mut self.writer, &value.to_string()) + .map_err(Error::io) + } + } + + #[inline] + fn serialize_f32(self, value: f32) -> Result<()> { + match value.classify() { + FpCategory::Nan | FpCategory::Infinite => { + try!( + self.formatter + .write_null(&mut self.writer) + .map_err(Error::io) + ); + } + _ => { + try!( + self.formatter + .write_f32(&mut self.writer, value) + .map_err(Error::io) + ); + } + } + Ok(()) + } + + #[inline] + fn serialize_f64(self, value: f64) -> Result<()> { + match value.classify() { + FpCategory::Nan | FpCategory::Infinite => { + try!( + self.formatter + .write_null(&mut self.writer) + .map_err(Error::io) + ); + } + _ => { + try!( + self.formatter + .write_f64(&mut self.writer, value) + .map_err(Error::io) + ); + } + } + Ok(()) + } + + #[inline] + fn serialize_char(self, value: char) -> Result<()> { + // A char encoded as UTF-8 takes 4 bytes at most. + let mut buf = [0; 4]; + self.serialize_str(value.encode_utf8(&mut buf)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result<()> { + try!(format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io)); + Ok(()) + } + + #[inline] + fn serialize_bytes(self, value: &[u8]) -> Result<()> { + use serde::ser::SerializeSeq; + let mut seq = try!(self.serialize_seq(Some(value.len()))); + for byte in value { + try!(seq.serialize_element(byte)); + } + seq.end() + } + + #[inline] + fn serialize_unit(self) -> Result<()> { + try!( + self.formatter + .write_null(&mut self.writer) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<()> { + self.serialize_str(variant) + } + + /// Serialize newtypes without an object wrapper. + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: ser::Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result<()> + where + T: ser::Serialize, + { + try!( + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io) + ); + try!(self.serialize_str(variant)); + try!( + self.formatter + .end_object_key(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io) + ); + try!(value.serialize(&mut *self)); + try!( + self.formatter + .end_object_value(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .end_object(&mut self.writer) + .map_err(Error::io) + ); + Ok(()) + } + + #[inline] + fn serialize_none(self) -> Result<()> { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + value.serialize(self) + } + + #[inline] + fn serialize_seq(self, len: Option) -> Result { + if len == Some(0) { + try!( + self.formatter + .begin_array(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .end_array(&mut self.writer) + .map_err(Error::io) + ); + Ok(Compound::Map { + ser: self, + state: State::Empty, + }) + } else { + try!( + self.formatter + .begin_array(&mut self.writer) + .map_err(Error::io) + ); + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + } + + #[inline] + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + try!( + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io) + ); + try!(self.serialize_str(variant)); + try!( + self.formatter + .end_object_key(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io) + ); + self.serialize_seq(Some(len)) + } + + #[inline] + fn serialize_map(self, len: Option) -> Result { + if len == Some(0) { + try!( + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .end_object(&mut self.writer) + .map_err(Error::io) + ); + Ok(Compound::Map { + ser: self, + state: State::Empty, + }) + } else { + try!( + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + ); + Ok(Compound::Map { + ser: self, + state: State::First, + }) + } + } + + #[cfg(not(feature = "arbitrary_precision"))] + #[inline] + fn serialize_struct(self, _name: &'static str, len: usize) -> Result { + self.serialize_map(Some(len)) + } + + #[cfg(feature = "arbitrary_precision")] + #[inline] + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + if name == SERDE_STRUCT_NAME { + Ok(Compound::Number { ser: self }) + } else { + self.serialize_map(Some(len)) + } + } + + #[inline] + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + try!( + self.formatter + .begin_object(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_key(&mut self.writer, true) + .map_err(Error::io) + ); + try!(self.serialize_str(variant)); + try!( + self.formatter + .end_object_key(&mut self.writer) + .map_err(Error::io) + ); + try!( + self.formatter + .begin_object_value(&mut self.writer) + .map_err(Error::io) + ); + self.serialize_map(Some(len)) + } + + fn collect_str(self, value: &T) -> Result + where + T: fmt::Display, + { + use std::fmt::Write; + + struct Adapter<'ser, W: 'ser, F: 'ser> { + writer: &'ser mut W, + formatter: &'ser mut F, + error: Option, + } + + impl<'ser, W, F> Write for Adapter<'ser, W, F> + where + W: io::Write, + F: Formatter, + { + fn write_str(&mut self, s: &str) -> fmt::Result { + assert!(self.error.is_none()); + match format_escaped_str_contents(self.writer, self.formatter, s) { + Ok(()) => Ok(()), + Err(err) => { + self.error = Some(err); + Err(fmt::Error) + } + } + } + } + + try!( + self.formatter + .begin_string(&mut self.writer) + .map_err(Error::io) + ); + { + let mut adapter = Adapter { + writer: &mut self.writer, + formatter: &mut self.formatter, + error: None, + }; + match write!(adapter, "{}", value) { + Ok(()) => assert!(adapter.error.is_none()), + Err(fmt::Error) => { + return Err(Error::io(adapter.error.expect("there should be an error"))); + } + } + } + try!( + self.formatter + .end_string(&mut self.writer) + .map_err(Error::io) + ); + Ok(()) + } +} + +#[derive(Eq, PartialEq)] +/// Not public API. Should be pub(crate). +#[doc(hidden)] +pub enum State { + Empty, + First, + Rest, +} + +/// Not public API. Should be pub(crate). +#[doc(hidden)] +pub enum Compound<'a, W: 'a, F: 'a> { + Map { + ser: &'a mut Serializer, + state: State, + }, + #[cfg(feature = "arbitrary_precision")] + Number { ser: &'a mut Serializer }, +} + +impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + match *self { + Compound::Map { + ref mut ser, + ref mut state, + } => { + try!( + ser.formatter + .begin_array_value(&mut ser.writer, *state == State::First) + .map_err(Error::io) + ); + *state = State::Rest; + try!(value.serialize(&mut **ser)); + try!( + ser.formatter + .end_array_value(&mut ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => try!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)), + } + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + ser::SerializeSeq::end(self) + } +} + +impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + ser::SerializeSeq::end(self) + } +} + +impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => try!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)), + } + try!( + ser.formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io) + ); + try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ser::Serialize, + { + match *self { + Compound::Map { + ref mut ser, + ref mut state, + } => { + try!( + ser.formatter + .begin_object_key(&mut ser.writer, *state == State::First) + .map_err(Error::io) + ); + *state = State::Rest; + + try!(key.serialize(MapKeySerializer { ser: *ser })); + + try!( + ser.formatter + .end_object_key(&mut ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } + + #[inline] + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ser::Serialize, + { + match *self { + Compound::Map { ref mut ser, .. } => { + try!( + ser.formatter + .begin_object_value(&mut ser.writer) + .map_err(Error::io) + ); + try!(value.serialize(&mut **ser)); + try!( + ser.formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)), + } + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } +} + +impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ser::Serialize, + { + match *self { + Compound::Map { .. } => { + try!(ser::SerializeMap::serialize_key(self, key)); + ser::SerializeMap::serialize_value(self, value) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { ref mut ser, .. } => { + if key == SERDE_STRUCT_FIELD_NAME { + try!(value.serialize(NumberStrEmitter(&mut *ser))); + Ok(()) + } else { + Err(invalid_number()) + } + } + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { .. } => ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => Ok(()), + } + } +} + +impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ser::Serialize, + { + match *self { + Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value), + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } + + #[inline] + fn end(self) -> Result<()> { + match self { + Compound::Map { ser, state } => { + match state { + State::Empty => {} + _ => try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)), + } + try!( + ser.formatter + .end_object_value(&mut ser.writer) + .map_err(Error::io) + ); + try!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + Compound::Number { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer<'a, W: 'a, F: 'a> { + ser: &'a mut Serializer, +} + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> +where + W: io::Write, + F: Formatter, +{ + type Ok = (); + type Error = Error; + + #[inline] + fn serialize_str(self, value: &str) -> Result<()> { + self.ser.serialize_str(value) + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result<()> { + self.ser.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> + where + T: ser::Serialize, + { + value.serialize(self) + } + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, _value: bool) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_i8(self, value: i8) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_i8(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_i16(self, value: i16) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_i16(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_i32(self, value: i32) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_i32(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_i64(self, value: i64) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_i64(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + serde_if_integer128! { + fn serialize_i128(self, value: i128) -> Result<()> { + self.ser + .formatter + .write_number_str(&mut self.ser.writer, &value.to_string()) + .map_err(Error::io) + } + } + + fn serialize_u8(self, value: u8) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_u8(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_u16(self, value: u16) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_u16(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_u32(self, value: u32) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_u32(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + fn serialize_u64(self, value: u64) -> Result<()> { + try!( + self.ser + .formatter + .begin_string(&mut self.ser.writer) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .write_u64(&mut self.ser.writer, value) + .map_err(Error::io) + ); + try!( + self.ser + .formatter + .end_string(&mut self.ser.writer) + .map_err(Error::io) + ); + Ok(()) + } + + serde_if_integer128! { + fn serialize_u128(self, value: u128) -> Result<()> { + self.ser + .formatter + .write_number_str(&mut self.ser.writer, &value.to_string()) + .map_err(Error::io) + } + } + + fn serialize_f32(self, _value: f32) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_f64(self, _value: f64) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_char(self, value: char) -> Result<()> { + self.ser.serialize_str(&value.to_string()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<()> + where + T: ser::Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result<()> { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result<()> + where + T: ser::Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer); + +#[cfg(feature = "arbitrary_precision")] +impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> { + type Ok = (); + type Error = Error; + + type SerializeSeq = Impossible<(), Error>; + type SerializeTuple = Impossible<(), Error>; + type SerializeTupleStruct = Impossible<(), Error>; + type SerializeTupleVariant = Impossible<(), Error>; + type SerializeMap = Impossible<(), Error>; + type SerializeStruct = Impossible<(), Error>; + type SerializeStructVariant = Impossible<(), Error>; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_number()) + } + + serde_if_integer128! { + fn serialize_i128(self, _v: i128) -> Result { + Err(invalid_number()) + } + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_number()) + } + + serde_if_integer128! { + fn serialize_u128(self, _v: u128) -> Result { + Err(invalid_number()) + } + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result { + let NumberStrEmitter(serializer) = self; + serializer + .formatter + .write_number_str(&mut serializer.writer, value) + .map_err(Error::io) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result { + Err(invalid_number()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + _value: &T, + ) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } +} + +/// Represents a character escape code in a type-safe manner. +pub enum CharEscape { + /// An escaped quote `"` + Quote, + /// An escaped reverse solidus `\` + ReverseSolidus, + /// An escaped solidus `/` + Solidus, + /// An escaped backspace character (usually escaped as `\b`) + Backspace, + /// An escaped form feed character (usually escaped as `\f`) + FormFeed, + /// An escaped line feed character (usually escaped as `\n`) + LineFeed, + /// An escaped carriage return character (usually escaped as `\r`) + CarriageReturn, + /// An escaped tab character (usually escaped as `\t`) + Tab, + /// An escaped ASCII plane control character (usually escaped as + /// `\u00XX` where `XX` are two hex characters) + AsciiControl(u8), +} + +impl CharEscape { + #[inline] + fn from_escape_table(escape: u8, byte: u8) -> CharEscape { + match escape { + self::BB => CharEscape::Backspace, + self::TT => CharEscape::Tab, + self::NN => CharEscape::LineFeed, + self::FF => CharEscape::FormFeed, + self::RR => CharEscape::CarriageReturn, + self::QU => CharEscape::Quote, + self::BS => CharEscape::ReverseSolidus, + self::U => CharEscape::AsciiControl(byte), + _ => unreachable!(), + } + } +} + +/// This trait abstracts away serializing the JSON control characters, which allows the user to +/// optionally pretty print the JSON output. +pub trait Formatter { + /// Writes a `null` value to the specified writer. + #[inline] + fn write_null(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"null") + } + + /// Writes a `true` or `false` value to the specified writer. + #[inline] + fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> + where + W: io::Write, + { + let s = if value { + b"true" as &[u8] + } else { + b"false" as &[u8] + }; + writer.write_all(s) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i8(&mut self, writer: &mut W, value: i8) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i16(&mut self, writer: &mut W, value: i16) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i32(&mut self, writer: &mut W, value: i32) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `-123` to the specified writer. + #[inline] + fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u8(&mut self, writer: &mut W, value: u8) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u16(&mut self, writer: &mut W, value: u16) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u32(&mut self, writer: &mut W, value: u32) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes an integer value like `123` to the specified writer. + #[inline] + fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> + where + W: io::Write, + { + itoa::write(writer, value).map(drop) + } + + /// Writes a floating point value like `-31.26e+12` to the specified writer. + #[inline] + fn write_f32(&mut self, writer: &mut W, value: f32) -> io::Result<()> + where + W: io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a floating point value like `-31.26e+12` to the specified writer. + #[inline] + fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> + where + W: io::Write, + { + let mut buffer = ryu::Buffer::new(); + let s = buffer.format(value); + writer.write_all(s.as_bytes()) + } + + /// Writes a number that has already been rendered to a string. + #[inline] + fn write_number_str(&mut self, writer: &mut W, value: &str) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(value.as_bytes()) + } + + /// Called before each series of `write_string_fragment` and + /// `write_char_escape`. Writes a `"` to the specified writer. + #[inline] + fn begin_string(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"\"") + } + + /// Called after each series of `write_string_fragment` and + /// `write_char_escape`. Writes a `"` to the specified writer. + #[inline] + fn end_string(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"\"") + } + + /// Writes a string fragment that doesn't need any escaping to the + /// specified writer. + #[inline] + fn write_string_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(fragment.as_bytes()) + } + + /// Writes a character escape code to the specified writer. + #[inline] + fn write_char_escape( + &mut self, + writer: &mut W, + char_escape: CharEscape, + ) -> io::Result<()> + where + W: io::Write, + { + use self::CharEscape::*; + + let s = match char_escape { + Quote => b"\\\"", + ReverseSolidus => b"\\\\", + Solidus => b"\\/", + Backspace => b"\\b", + FormFeed => b"\\f", + LineFeed => b"\\n", + CarriageReturn => b"\\r", + Tab => b"\\t", + AsciiControl(byte) => { + static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; + let bytes = &[ + b'\\', + b'u', + b'0', + b'0', + HEX_DIGITS[(byte >> 4) as usize], + HEX_DIGITS[(byte & 0xF) as usize], + ]; + return writer.write_all(bytes); + } + }; + + writer.write_all(s) + } + + /// Called before every array. Writes a `[` to the specified + /// writer. + #[inline] + fn begin_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"[") + } + + /// Called after every array. Writes a `]` to the specified + /// writer. + #[inline] + fn end_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"]") + } + + /// Called before every array value. Writes a `,` if needed to + /// the specified writer. + #[inline] + fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: io::Write, + { + if first { + Ok(()) + } else { + writer.write_all(b",") + } + } + + /// Called after every array value. + #[inline] + fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + Ok(()) + } + + /// Called before every object. Writes a `{` to the specified + /// writer. + #[inline] + fn begin_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"{") + } + + /// Called after every object. Writes a `}` to the specified + /// writer. + #[inline] + fn end_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b"}") + } + + /// Called before every object key. + #[inline] + fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: io::Write, + { + if first { + Ok(()) + } else { + writer.write_all(b",") + } + } + + /// Called after every object key. A `:` should be written to the + /// specified writer by either this method or + /// `begin_object_value`. + #[inline] + fn end_object_key(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + Ok(()) + } + + /// Called before every object value. A `:` should be written to + /// the specified writer by either this method or + /// `end_object_key`. + #[inline] + fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b":") + } + + /// Called after every object value. + #[inline] + fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + Ok(()) + } +} + +/// This structure compacts a JSON value with no extra whitespace. +#[derive(Clone, Debug)] +pub struct CompactFormatter; + +impl Formatter for CompactFormatter {} + +/// This structure pretty prints a JSON value to make it human readable. +#[derive(Clone, Debug)] +pub struct PrettyFormatter<'a> { + current_indent: usize, + has_value: bool, + indent: &'a [u8], +} + +impl<'a> PrettyFormatter<'a> { + /// Construct a pretty printer formatter that defaults to using two spaces for indentation. + pub fn new() -> Self { + PrettyFormatter::with_indent(b" ") + } + + /// Construct a pretty printer formatter that uses the `indent` string for indentation. + pub fn with_indent(indent: &'a [u8]) -> Self { + PrettyFormatter { + current_indent: 0, + has_value: false, + indent: indent, + } + } +} + +impl<'a> Default for PrettyFormatter<'a> { + fn default() -> Self { + PrettyFormatter::new() + } +} + +impl<'a> Formatter for PrettyFormatter<'a> { + #[inline] + fn begin_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.current_indent += 1; + self.has_value = false; + writer.write_all(b"[") + } + + #[inline] + fn end_array(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.current_indent -= 1; + + if self.has_value { + try!(writer.write_all(b"\n")); + try!(indent(writer, self.current_indent, self.indent)); + } + + writer.write_all(b"]") + } + + #[inline] + fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: io::Write, + { + if first { + try!(writer.write_all(b"\n")); + } else { + try!(writer.write_all(b",\n")); + } + try!(indent(writer, self.current_indent, self.indent)); + Ok(()) + } + + #[inline] + fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.has_value = true; + Ok(()) + } + + #[inline] + fn begin_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.current_indent += 1; + self.has_value = false; + writer.write_all(b"{") + } + + #[inline] + fn end_object(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.current_indent -= 1; + + if self.has_value { + try!(writer.write_all(b"\n")); + try!(indent(writer, self.current_indent, self.indent)); + } + + writer.write_all(b"}") + } + + #[inline] + fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> + where + W: io::Write, + { + if first { + try!(writer.write_all(b"\n")); + } else { + try!(writer.write_all(b",\n")); + } + indent(writer, self.current_indent, self.indent) + } + + #[inline] + fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + writer.write_all(b": ") + } + + #[inline] + fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> + where + W: io::Write, + { + self.has_value = true; + Ok(()) + } +} + +fn format_escaped_str( + writer: &mut W, + formatter: &mut F, + value: &str, +) -> io::Result<()> +where + W: io::Write, + F: Formatter, +{ + try!(formatter.begin_string(writer)); + try!(format_escaped_str_contents(writer, formatter, value)); + try!(formatter.end_string(writer)); + Ok(()) +} + +fn format_escaped_str_contents( + writer: &mut W, + formatter: &mut F, + value: &str, +) -> io::Result<()> +where + W: io::Write, + F: Formatter, +{ + let bytes = value.as_bytes(); + + let mut start = 0; + + for (i, &byte) in bytes.iter().enumerate() { + let escape = ESCAPE[byte as usize]; + if escape == 0 { + continue; + } + + if start < i { + try!(formatter.write_string_fragment(writer, &value[start..i])); + } + + let char_escape = CharEscape::from_escape_table(escape, byte); + try!(formatter.write_char_escape(writer, char_escape)); + + start = i + 1; + } + + if start != bytes.len() { + try!(formatter.write_string_fragment(writer, &value[start..])); + } + + Ok(()) +} + +const BB: u8 = b'b'; // \x08 +const TT: u8 = b't'; // \x09 +const NN: u8 = b'n'; // \x0A +const FF: u8 = b'f'; // \x0C +const RR: u8 = b'r'; // \x0D +const QU: u8 = b'"'; // \x22 +const BS: u8 = b'\\'; // \x5C +const U: u8 = b'u'; // \x00...\x1F except the ones above + +// Lookup table of escape sequences. A value of b'x' at index i means that byte +// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped. +#[cfg_attr(rustfmt, rustfmt_skip)] +static ESCAPE: [u8; 256] = [ + // 1 2 3 4 5 6 7 8 9 A B C D E F + U, U, U, U, U, U, U, U, BB, TT, NN, U, FF, RR, U, U, // 0 + U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, // 1 + 0, 0, QU, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BS, 0, 0, 0, // 5 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F +]; + +/// Serialize the given data structure as JSON into the IO stream. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_writer(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: ser::Serialize, +{ + let mut ser = Serializer::new(writer); + try!(value.serialize(&mut ser)); + Ok(()) +} + +/// Serialize the given data structure as pretty-printed JSON into the IO +/// stream. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_writer_pretty(writer: W, value: &T) -> Result<()> +where + W: io::Write, + T: ser::Serialize, +{ + let mut ser = Serializer::pretty(writer); + try!(value.serialize(&mut ser)); + Ok(()) +} + +/// Serialize the given data structure as a JSON byte vector. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_vec(value: &T) -> Result> +where + T: ser::Serialize, +{ + let mut writer = Vec::with_capacity(128); + try!(to_writer(&mut writer, value)); + Ok(writer) +} + +/// Serialize the given data structure as a pretty-printed JSON byte vector. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_vec_pretty(value: &T) -> Result> +where + T: ser::Serialize, +{ + let mut writer = Vec::with_capacity(128); + try!(to_writer_pretty(&mut writer, value)); + Ok(writer) +} + +/// Serialize the given data structure as a String of JSON. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_string(value: &T) -> Result +where + T: ser::Serialize, +{ + let vec = try!(to_vec(value)); + let string = unsafe { + // We do not emit invalid UTF-8. + String::from_utf8_unchecked(vec) + }; + Ok(string) +} + +/// Serialize the given data structure as a pretty-printed String of JSON. +/// +/// # Errors +/// +/// Serialization can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +#[inline] +pub fn to_string_pretty(value: &T) -> Result +where + T: ser::Serialize, +{ + let vec = try!(to_vec_pretty(value)); + let string = unsafe { + // We do not emit invalid UTF-8. + String::from_utf8_unchecked(vec) + }; + Ok(string) +} + +fn indent(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()> +where + W: io::Write, +{ + for _ in 0..n { + try!(wr.write_all(s)); + } + + Ok(()) +} diff --git a/third_party/rust/serde_json/src/value/de.rs b/third_party/rust/serde_json/src/value/de.rs new file mode 100644 index 000000000000..67b18bebb548 --- /dev/null +++ b/third_party/rust/serde_json/src/value/de.rs @@ -0,0 +1,1376 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::borrow::Cow; +use std::fmt; +use std::slice; +use std::str; +use std::vec; + +use serde; +use serde::de::{ + Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess, SeqAccess, + Unexpected, VariantAccess, Visitor, +}; + +use error::Error; +use map::Map; +use number::Number; +use value::Value; + +#[cfg(feature = "arbitrary_precision")] +use serde::de; + +#[cfg(feature = "arbitrary_precision")] +use number::{NumberFromString, SERDE_STRUCT_FIELD_NAME}; + +impl<'de> Deserialize<'de> for Value { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct ValueVisitor; + + impl<'de> Visitor<'de> for ValueVisitor { + type Value = Value; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("any valid JSON value") + } + + #[inline] + fn visit_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + } + + #[inline] + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + self.visit_string(String::from(value)) + } + + #[inline] + fn visit_string(self, value: String) -> Result { + Ok(Value::String(value)) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(elem) = try!(visitor.next_element()) { + vec.push(elem); + } + + Ok(Value::Array(vec)) + } + + #[cfg(not(feature = "arbitrary_precision"))] + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + let mut values = Map::new(); + + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(Value::Object(values)) + } + + #[cfg(feature = "arbitrary_precision")] + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + let mut key = String::new(); + let number = visitor.next_key_seed(NumberOrObject { key: &mut key })?; + match number { + Some(true) => { + let number: NumberFromString = visitor.next_value()?; + return Ok(Value::Number(number.value)); + } + None => return Ok(Value::Object(Map::new())), + Some(false) => {} + } + + let mut values = Map::new(); + + values.insert(key, try!(visitor.next_value())); + while let Some((key, value)) = try!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(Value::Object(values)) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl str::FromStr for Value { + type Err = Error; + fn from_str(s: &str) -> Result { + super::super::de::from_str(s) + } +} + +macro_rules! deserialize_prim_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + } +} + +fn visit_array<'de, V>(array: Vec, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqDeserializer::new(array); + let seq = try!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +fn visit_object<'de, V>(object: Map, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = object.len(); + let mut deserializer = MapDeserializer::new(object); + let map = try!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } +} + +impl<'de> serde::Deserializer<'de> for Value { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(v), + Value::Number(n) => n.deserialize_any(visitor), + Value::String(v) => visitor.visit_string(v), + Value::Array(v) => visit_array(v, visitor), + Value::Object(v) => visit_object(v, visitor), + } + } + + deserialize_prim_number!(deserialize_i8); + deserialize_prim_number!(deserialize_i16); + deserialize_prim_number!(deserialize_i32); + deserialize_prim_number!(deserialize_i64); + deserialize_prim_number!(deserialize_u8); + deserialize_prim_number!(deserialize_u16); + deserialize_prim_number!(deserialize_u32); + deserialize_prim_number!(deserialize_u64); + deserialize_prim_number!(deserialize_f32); + deserialize_prim_number!(deserialize_f64); + + serde_if_integer128! { + deserialize_prim_number!(deserialize_i128); + deserialize_prim_number!(deserialize_u128); + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + #[inline] + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match self { + Value::Object(value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + Value::String(variant) => (variant, None), + other => { + return Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumDeserializer { + variant: variant, + value: value, + }) + } + + #[inline] + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_string(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::String(v) => visitor.visit_string(v), + Value::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Object(v) => visit_object(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + Value::Array(v) => visit_array(v, visitor), + Value::Object(v) => visit_object(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } +} + +struct EnumDeserializer { + variant: String, + value: Option, +} + +impl<'de> EnumAccess<'de> for EnumDeserializer { + type Error = Error; + type Variant = VariantDeserializer; + + fn variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +struct VariantDeserializer { + value: Option, +} + +impl<'de> VariantAccess<'de> for VariantDeserializer { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Array(v)) => { + serde::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor) + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(Value::Object(v)) => { + serde::Deserializer::deserialize_any(MapDeserializer::new(v), visitor) + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + _ => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqDeserializer { + iter: vec::IntoIter, +} + +impl SeqDeserializer { + fn new(vec: Vec) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> serde::Deserializer<'de> for SeqDeserializer { + type Error = Error; + + #[inline] + fn deserialize_any(mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = try!(visitor.visit_seq(&mut self)); + let remaining = self.iter.len(); + if remaining == 0 { + Ok(ret) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } + } + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'de> SeqAccess<'de> for SeqDeserializer { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapDeserializer { + iter: as IntoIterator>::IntoIter, + value: Option, +} + +impl MapDeserializer { + fn new(map: Map) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Owned(key), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +impl<'de> serde::Deserializer<'de> for MapDeserializer { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_map(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +macro_rules! deserialize_value_ref_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Number(ref n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Number(ref n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + } +} + +fn visit_array_ref<'de, V>(array: &'de [Value], visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqRefDeserializer::new(array); + let seq = try!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +fn visit_object_ref<'de, V>(object: &'de Map, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = object.len(); + let mut deserializer = MapRefDeserializer::new(object); + let map = try!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } +} + +impl<'de> serde::Deserializer<'de> for &'de Value { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_unit(), + Value::Bool(v) => visitor.visit_bool(v), + Value::Number(ref n) => n.deserialize_any(visitor), + Value::String(ref v) => visitor.visit_borrowed_str(v), + Value::Array(ref v) => visit_array_ref(v, visitor), + Value::Object(ref v) => visit_object_ref(v, visitor), + } + } + + deserialize_value_ref_number!(deserialize_i8); + deserialize_value_ref_number!(deserialize_i16); + deserialize_value_ref_number!(deserialize_i32); + deserialize_value_ref_number!(deserialize_i64); + deserialize_value_ref_number!(deserialize_u8); + deserialize_value_ref_number!(deserialize_u16); + deserialize_value_ref_number!(deserialize_u32); + deserialize_value_ref_number!(deserialize_u64); + deserialize_value_ref_number!(deserialize_f32); + deserialize_value_ref_number!(deserialize_f64); + + serde_if_integer128! { + deserialize_prim_number!(deserialize_i128); + deserialize_prim_number!(deserialize_u128); + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let (variant, value) = match *self { + Value::Object(ref value) => { + let mut iter = value.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + (variant, Some(value)) + } + Value::String(ref variant) => (variant, None), + ref other => { + return Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )); + } + }; + + visitor.visit_enum(EnumRefDeserializer { + variant: variant, + value: value, + }) + } + + #[inline] + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::String(ref v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::String(ref v) => visitor.visit_borrowed_str(v), + Value::Array(ref v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Array(ref v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Object(ref v) => visit_object_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match *self { + Value::Array(ref v) => visit_array_ref(v, visitor), + Value::Object(ref v) => visit_object_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } +} + +struct EnumRefDeserializer<'de> { + variant: &'de str, + value: Option<&'de Value>, +} + +impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { + type Error = Error; + type Variant = VariantRefDeserializer<'de>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantRefDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +struct VariantRefDeserializer<'de> { + value: Option<&'de Value>, +} + +impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(&Value::Array(ref v)) => { + serde::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor) + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(&Value::Object(ref v)) => { + serde::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor) + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + _ => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqRefDeserializer<'de> { + iter: slice::Iter<'de, Value>, +} + +impl<'de> SeqRefDeserializer<'de> { + fn new(slice: &'de [Value]) -> Self { + SeqRefDeserializer { iter: slice.iter() } + } +} + +impl<'de> serde::Deserializer<'de> for SeqRefDeserializer<'de> { + type Error = Error; + + #[inline] + fn deserialize_any(mut self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.iter.len(); + if len == 0 { + visitor.visit_unit() + } else { + let ret = try!(visitor.visit_seq(&mut self)); + let remaining = self.iter.len(); + if remaining == 0 { + Ok(ret) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } + } + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapRefDeserializer<'de> { + iter: <&'de Map as IntoIterator>::IntoIter, + value: Option<&'de Value>, +} + +impl<'de> MapRefDeserializer<'de> { + fn new(map: &'de Map) -> Self { + MapRefDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Borrowed(&**key), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +impl<'de> serde::Deserializer<'de> for MapRefDeserializer<'de> { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_map(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct enum identifier ignored_any + } +} + +struct MapKeyDeserializer<'de> { + key: Cow<'de, str>, +} + +macro_rules! deserialize_integer_key { + ($method:ident => $visit:ident) => { + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match (self.key.parse(), self.key) { + (Ok(integer), _) => visitor.$visit(integer), + (Err(_), Cow::Borrowed(s)) => visitor.visit_borrowed_str(s), + (Err(_), Cow::Owned(s)) => visitor.visit_string(s), + } + } + } +} + +impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.key.into_deserializer().deserialize_any(visitor) + } + + deserialize_integer_key!(deserialize_i8 => visit_i8); + deserialize_integer_key!(deserialize_i16 => visit_i16); + deserialize_integer_key!(deserialize_i32 => visit_i32); + deserialize_integer_key!(deserialize_i64 => visit_i64); + deserialize_integer_key!(deserialize_u8 => visit_u8); + deserialize_integer_key!(deserialize_u16 => visit_u16); + deserialize_integer_key!(deserialize_u32 => visit_u32); + deserialize_integer_key!(deserialize_u64 => visit_u64); + + serde_if_integer128! { + deserialize_integer_key!(deserialize_i128 => visit_i128); + deserialize_integer_key!(deserialize_u128 => visit_u128); + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.key + .into_deserializer() + .deserialize_enum(name, variants, visitor) + } + + forward_to_deserialize_any! { + bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberOrObject<'a> { + key: &'a mut String, +} + +#[cfg(feature = "arbitrary_precision")] +impl<'a, 'de> DeserializeSeed<'de> for NumberOrObject<'a> { + type Value = bool; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_any(self) + } +} + +#[cfg(feature = "arbitrary_precision")] +impl<'a, 'de> Visitor<'de> for NumberOrObject<'a> { + type Value = bool; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string key") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + if s == SERDE_STRUCT_FIELD_NAME { + Ok(true) + } else { + self.key.push_str(s); + Ok(false) + } + } + + fn visit_string(self, s: String) -> Result + where + E: de::Error, + { + if s == SERDE_STRUCT_FIELD_NAME { + Ok(true) + } else { + *self.key = s; + Ok(false) + } + } +} + +impl Value { + #[cold] + fn invalid_type(&self, exp: &Expected) -> E + where + E: serde::de::Error, + { + serde::de::Error::invalid_type(self.unexpected(), exp) + } + + #[cold] + fn unexpected(&self) -> Unexpected { + match *self { + Value::Null => Unexpected::Unit, + Value::Bool(b) => Unexpected::Bool(b), + Value::Number(ref n) => n.unexpected(), + Value::String(ref s) => Unexpected::Str(s), + Value::Array(_) => Unexpected::Seq, + Value::Object(_) => Unexpected::Map, + } + } +} diff --git a/third_party/rust/serde_json/src/value/from.rs b/third_party/rust/serde_json/src/value/from.rs new file mode 100644 index 000000000000..0afefd3cb53f --- /dev/null +++ b/third_party/rust/serde_json/src/value/from.rs @@ -0,0 +1,266 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::borrow::Cow; + +use super::Value; +use map::Map; +use number::Number; + +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 +} + +impl From for Value { + /// Convert 32-bit floating point number to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let f: f32 = 13.37; + /// let x: Value = f.into(); + /// # } + /// ``` + fn from(f: f32) -> Self { + From::from(f as f64) + } +} + +impl From for Value { + /// Convert 64-bit floating point number to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let f: f64 = 13.37; + /// let x: Value = f.into(); + /// # } + /// ``` + fn from(f: f64) -> Self { + Number::from_f64(f).map_or(Value::Null, Value::Number) + } +} + +impl From for Value { + /// Convert boolean to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let b = false; + /// let x: Value = b.into(); + /// # } + /// ``` + fn from(f: bool) -> Self { + Value::Bool(f) + } +} + +impl From for Value { + /// Convert `String` to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let s: String = "lorem".to_string(); + /// let x: Value = s.into(); + /// # } + /// ``` + fn from(f: String) -> Self { + Value::String(f) + } +} + +impl<'a> From<&'a str> for Value { + /// Convert string slice to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let s: &str = "lorem"; + /// let x: Value = s.into(); + /// # } + /// ``` + fn from(f: &str) -> Self { + Value::String(f.to_string()) + } +} + +impl<'a> From> for Value { + /// Convert copy-on-write string to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Borrowed("lorem"); + /// let x: Value = s.into(); + /// # } + /// ``` + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Owned("lorem".to_string()); + /// let x: Value = s.into(); + /// # } + /// ``` + fn from(f: Cow<'a, str>) -> Self { + Value::String(f.into_owned()) + } +} + +impl From> for Value { + /// Convert map (with string keys) to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::{Map, Value}; + /// + /// let mut m = Map::new(); + /// m.insert("Lorem".to_string(), "ipsum".into()); + /// let x: Value = m.into(); + /// # } + /// ``` + fn from(f: Map) -> Self { + Value::Object(f) + } +} + +impl> From> for Value { + /// Convert a `Vec` to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let v = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// # } + /// ``` + fn from(f: Vec) -> Self { + Value::Array(f.into_iter().map(Into::into).collect()) + } +} + +impl<'a, T: Clone + Into> From<&'a [T]> for Value { + /// Convert a slice to `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// # } + /// ``` + fn from(f: &'a [T]) -> Self { + Value::Array(f.into_iter().cloned().map(Into::into).collect()) + } +} + +impl> ::std::iter::FromIterator for Value { + /// Convert an iteratable type to a `Value` + /// + /// # Examples + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let v = std::iter::repeat(42).take(5); + /// let x: Value = v.collect(); + /// # } + /// ``` + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into_iter().collect(); + /// # } + /// ``` + /// + /// ```rust + /// # extern crate serde_json; + /// # + /// # fn main() { + /// use std::iter::FromIterator; + /// use serde_json::Value; + /// + /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); + /// # } + /// ``` + fn from_iter>(iter: I) -> Self { + Value::Array(iter.into_iter().map(Into::into).collect()) + } +} diff --git a/third_party/rust/serde_json/src/value/index.rs b/third_party/rust/serde_json/src/value/index.rs new file mode 100644 index 000000000000..87c61eb10c17 --- /dev/null +++ b/third_party/rust/serde_json/src/value/index.rs @@ -0,0 +1,274 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; +use std::ops; + +use super::Value; +use map::Map; + +/// A type that can be used to index into a `serde_json::Value`. +/// +/// The [`get`] and [`get_mut`] methods of `Value` accept any type that +/// implements `Index`, as does the [square-bracket indexing operator]. This +/// trait is implemented for strings which are used as the index into a JSON +/// map, and for `usize` which is used as the index into a JSON array. +/// +/// [`get`]: ../enum.Value.html#method.get +/// [`get_mut`]: ../enum.Value.html#method.get_mut +/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_json; +/// # +/// # fn main() { +/// let data = json!({ "inner": [1, 2, 3] }); +/// +/// // Data is a JSON map so it can be indexed with a string. +/// let inner = &data["inner"]; +/// +/// // Inner is a JSON array so it can be indexed with an integer. +/// let first = &inner[0]; +/// +/// assert_eq!(first, 1); +/// # } +/// ``` +pub trait Index: private::Sealed { + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; + + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; + + /// Panic if array index out of bounds. If key is not already in the object, + /// insert it with a value of null. Panic if Value is a type that cannot be + /// indexed into, except if Value is null then it can be treated as an empty + /// object. + #[doc(hidden)] + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; +} + +impl Index for usize { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match *v { + Value::Array(ref vec) => vec.get(*self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Array(ref mut vec) => vec.get_mut(*self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + match *v { + Value::Array(ref mut vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of JSON array of length {}", + self, len + ) + }) + } + _ => panic!("cannot access index {} of JSON {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match *v { + Value::Object(ref map) => map.get(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match *v { + Value::Object(ref mut map) => map.get_mut(self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + if let Value::Null = *v { + *v = Value::Object(Map::new()); + } + match *v { + Value::Object(ref mut map) => map.entry(self.to_owned()).or_insert(Value::Null), + _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), + } + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + self[..].index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + self[..].index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + self[..].index_or_insert(v) + } +} + +impl<'a, T: ?Sized> Index for &'a T +where + T: 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 String {} + impl<'a, T: ?Sized> Sealed for &'a T where T: Sealed {} +} + +/// Used in panic messages. +struct Type<'a>(&'a Value); + +impl<'a> fmt::Display for Type<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + Value::Null => formatter.write_str("null"), + Value::Bool(_) => formatter.write_str("boolean"), + Value::Number(_) => formatter.write_str("number"), + Value::String(_) => formatter.write_str("string"), + Value::Array(_) => formatter.write_str("array"), + Value::Object(_) => formatter.write_str("object"), + } + } +} + +// The usual semantics of Index is to panic on invalid indexing. +// +// That said, the usual semantics are for things like Vec and BTreeMap which +// have different use cases than Value. If you are working with a Vec, you know +// that you are working with a Vec and you can get the len of the Vec and make +// sure your indices are within bounds. The Value use cases are more +// loosey-goosey. You got some JSON from an endpoint and you want to pull values +// out of it. Outside of this Index impl, you already have the option of using +// value.as_array() and working with the Vec directly, or matching on +// Value::Array and getting the Vec directly. The Index impl means you can skip +// that and index directly into the thing using a concise syntax. You don't have +// to check the type, you don't have to check the len, it is all about what you +// expect the Value to look like. +// +// Basically the use cases that would be well served by panicking here are +// better served by using one of the other approaches: get and get_mut, +// as_array, or match. The value of this impl is that it adds a way of working +// with Value that is not well served by the existing approaches: concise and +// careless and sometimes that is exactly what you want. +impl ops::Index for Value +where + I: Index, +{ + type Output = Value; + + /// Index into a `serde_json::Value` using the syntax `value[0]` or + /// `value["k"]`. + /// + /// Returns `Value::Null` if the type of `self` does not match the type of + /// the index, for example if the index is a string and `self` is an array + /// or a number. Also returns `Value::Null` if the given key does not exist + /// in the map or the given index is not within the bounds of the array. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); + /// assert_eq!(data["x"]["y"][0], json!("z")); + /// + /// assert_eq!(data["a"], json!(null)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], json!(null)); // does not panic + /// # } + /// ``` + fn index(&self, index: I) -> &Value { + static NULL: Value = Value::Null; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl ops::IndexMut for Value +where + I: Index, +{ + /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be an array of length bigger + /// than the index. Indexing into a value that is not an array or an array + /// that is too small will panic. + /// + /// If the index is a string, the value must be an object or null which is + /// treated like an empty object. If the key is not already present in the + /// object, it will be inserted with a value of null. Indexing into a value + /// that is neither an object nor null will panic. + /// + /// # Examples + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut data = json!({ "x": 0 }); + /// + /// // replace an existing key + /// data["x"] = json!(1); + /// + /// // insert a new key + /// data["y"] = json!([false, false, false]); + /// + /// // replace an array value + /// data["y"][0] = json!(true); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = json!(true); + /// + /// println!("{}", data); + /// # } + /// ``` + fn index_mut(&mut self, index: I) -> &mut Value { + index.index_or_insert(self) + } +} diff --git a/third_party/rust/serde_json/src/value/mod.rs b/third_party/rust/serde_json/src/value/mod.rs new file mode 100644 index 000000000000..3362512df4d4 --- /dev/null +++ b/third_party/rust/serde_json/src/value/mod.rs @@ -0,0 +1,1126 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! The Value enum, a loosely typed way of representing any valid JSON value. +//! +//! # Constructing JSON +//! +//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value` +//! objects with very natural JSON syntax. In order to use this macro, +//! `serde_json` needs to be imported with the `#[macro_use]` attribute. +//! +//! ```rust +//! #[macro_use] +//! extern crate serde_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. +//! +//! ```rust +//! # #[macro_use] +//! # extern crate serde_json; +//! # +//! # fn random_phone() -> u16 { 0 } +//! # +//! # fn main() { +//! 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()) +//! ] +//! }); +//! # let _ = john; +//! # } +//! ``` +//! +//! 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. +//! +//! ```rust +//! extern crate serde_json; +//! +//! use serde_json::{Value, Error}; +//! +//! fn untyped_example() -> Result<(), Error> { +//! // Some JSON input data as a &str. Maybe this comes from the user. +//! let data = r#"{ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }"#; +//! +//! // Parse the string of data into serde_json::Value. +//! let v: Value = serde_json::from_str(data)?; +//! +//! // Access parts of the data by indexing with square brackets. +//! println!("Please call {} at the number {}", v["name"], v["phones"][0]); +//! +//! Ok(()) +//! } +//! # +//! # fn main() { +//! # untyped_example().unwrap(); +//! # } +//! ``` +//! +//! [macro]: https://docs.serde.rs/serde_json/macro.json.html +//! [from_str]: https://docs.serde.rs/serde_json/de/fn.from_str.html +//! [from_slice]: https://docs.serde.rs/serde_json/de/fn.from_slice.html +//! [from_reader]: https://docs.serde.rs/serde_json/de/fn.from_reader.html + +use std::fmt::{self, Debug}; +use std::io; +use std::mem; +use std::str; + +use serde::de::DeserializeOwned; +use serde::ser::Serialize; + +use error::Error; +pub use map::Map; +pub use number::Number; + +pub use self::index::Index; + +use self::ser::Serializer; + +/// Represents any valid JSON value. +/// +/// See the `serde_json::value` module documentation for usage examples. +#[derive(Clone, PartialEq)] +pub enum Value { + /// Represents a JSON null value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!(null); + /// # } + /// ``` + Null, + + /// Represents a JSON boolean. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!(true); + /// # } + /// ``` + Bool(bool), + + /// Represents a JSON number, whether integer or floating point. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!(12.5); + /// # } + /// ``` + Number(Number), + + /// Represents a JSON string. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!("a string"); + /// # } + /// ``` + String(String), + + /// Represents a JSON array. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!(["an", "array"]); + /// # } + /// ``` + Array(Vec), + + /// Represents a JSON object. + /// + /// By default the map is backed by a BTreeMap. Enable the `preserve_order` + /// feature of serde_json to use IndexMap instead, which preserves + /// entries in the order they are inserted into the map. In particular, this + /// allows JSON data to be deserialized into a Value and serialized to a + /// string while retaining the order of map keys in the input. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "an": "object" }); + /// # } + /// ``` + Object(Map), +} + +impl Debug for Value { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self { + Value::Null => formatter.debug_tuple("Null").finish(), + Value::Bool(v) => formatter.debug_tuple("Bool").field(&v).finish(), + Value::Number(ref v) => Debug::fmt(v, formatter), + Value::String(ref v) => formatter.debug_tuple("String").field(v).finish(), + Value::Array(ref v) => formatter.debug_tuple("Array").field(v).finish(), + Value::Object(ref v) => formatter.debug_tuple("Object").field(v).finish(), + } + } +} + +struct WriterFormatter<'a, 'b: 'a> { + inner: &'a mut fmt::Formatter<'b>, +} + +impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { + fn write(&mut self, buf: &[u8]) -> io::Result { + fn io_error(_: E) -> io::Error { + // Error value does not matter because fmt::Display impl below just + // maps it to fmt::Error + io::Error::new(io::ErrorKind::Other, "fmt error") + } + let s = try!(str::from_utf8(buf).map_err(io_error)); + try!(self.inner.write_str(s).map_err(io_error)); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } +} + +impl fmt::Display for Value { + /// Display a JSON value as a string. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let json = json!({ "city": "London", "street": "10 Downing Street" }); + /// + /// // Compact format: + /// // + /// // {"city":"London","street":"10 Downing Street"} + /// let compact = format!("{}", json); + /// assert_eq!(compact, + /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); + /// + /// // Pretty format: + /// // + /// // { + /// // "city": "London", + /// // "street": "10 Downing Street" + /// // } + /// let pretty = format!("{:#}", json); + /// assert_eq!(pretty, + /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); + /// # } + /// ``` + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let alternate = f.alternate(); + let mut wr = WriterFormatter { inner: f }; + if alternate { + // {:#} + super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) + } else { + // {} + super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) + } + } +} + +fn parse_index(s: &str) -> Option { + if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { + return None; + } + s.parse().ok() +} + +impl Value { + /// Index into a JSON array or map. A string index can be used to access a + /// value in a map, and a usize index can be used to access an element of an + /// array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let object = json!({ "A": 65, "B": 66, "C": 67 }); + /// assert_eq!(*object.get("A").unwrap(), json!(65)); + /// + /// let array = json!([ "A", "B", "C" ]); + /// assert_eq!(*array.get(2).unwrap(), json!("C")); + /// + /// assert_eq!(array.get("A"), None); + /// # } + /// ``` + /// + /// Square brackets can also be used to index into a value in a more concise + /// way. This returns `Value::Null` in cases where `get` would have returned + /// `None`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let object = json!({ + /// "A": ["a", "á", "à"], + /// "B": ["b", "b́"], + /// "C": ["c", "ć", "ć̣", "ḉ"], + /// }); + /// assert_eq!(object["B"][0], json!("b")); + /// + /// assert_eq!(object["D"], json!(null)); + /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); + /// # } + /// ``` + pub fn get(&self, index: I) -> Option<&Value> { + index.index_into(self) + } + + /// Mutably index into a JSON array or map. A string index can be used to + /// access a value in a map, and a usize index can be used to access an + /// element of an array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); + /// *object.get_mut("A").unwrap() = json!(69); + /// + /// let mut array = json!([ "A", "B", "C" ]); + /// *array.get_mut(2).unwrap() = json!("D"); + /// # } + /// ``` + pub fn get_mut(&mut self, index: I) -> Option<&mut Value> { + index.index_into_mut(self) + } + + /// Returns true if the `Value` is an Object. Returns false otherwise. + /// + /// For any Value on which `is_object` returns true, `as_object` and + /// `as_object_mut` are guaranteed to return the map representation of the + /// object. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// assert!(obj.is_object()); + /// assert!(obj["a"].is_object()); + /// + /// // array, not an object + /// assert!(!obj["b"].is_object()); + /// # } + /// ``` + pub fn is_object(&self) -> bool { + self.as_object().is_some() + } + + /// If the `Value` is an Object, returns the associated Map. Returns None + /// otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// // The length of `{"nested": true}` is 1 entry. + /// assert_eq!(v["a"].as_object().unwrap().len(), 1); + /// + /// // The array `["an", "array"]` is not an object. + /// assert_eq!(v["b"].as_object(), None); + /// # } + /// ``` + pub fn as_object(&self) -> Option<&Map> { + match *self { + Value::Object(ref map) => Some(map), + _ => None, + } + } + + /// If the `Value` is an Object, returns the associated mutable Map. + /// Returns None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut v = json!({ "a": { "nested": true } }); + /// + /// v["a"].as_object_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": {} })); + /// # } + /// + /// ``` + pub fn as_object_mut(&mut self) -> Option<&mut Map> { + match *self { + Value::Object(ref mut map) => Some(map), + _ => None, + } + } + + /// Returns true if the `Value` is an Array. Returns false otherwise. + /// + /// For any Value on which `is_array` returns true, `as_array` and + /// `as_array_mut` are guaranteed to return the vector representing the + /// array. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// assert!(obj["a"].is_array()); + /// + /// // an object, not an array + /// assert!(!obj["b"].is_array()); + /// # } + /// ``` + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// If the `Value` is an Array, returns the associated vector. Returns None + /// otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// // The length of `["an", "array"]` is 2 elements. + /// assert_eq!(v["a"].as_array().unwrap().len(), 2); + /// + /// // The object `{"an": "object"}` is not an array. + /// assert_eq!(v["b"].as_array(), None); + /// # } + /// ``` + pub fn as_array(&self) -> Option<&Vec> { + match *self { + Value::Array(ref array) => Some(&*array), + _ => None, + } + } + + /// If the `Value` is an Array, returns the associated mutable vector. + /// Returns None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut v = json!({ "a": ["an", "array"] }); + /// + /// v["a"].as_array_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": [] })); + /// # } + /// ``` + pub fn as_array_mut(&mut self) -> Option<&mut Vec> { + match *self { + Value::Array(ref mut list) => Some(list), + _ => None, + } + } + + /// Returns true if the `Value` is a String. Returns false otherwise. + /// + /// For any Value on which `is_string` returns true, `as_str` is guaranteed + /// to return the string slice. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert!(v["a"].is_string()); + /// + /// // The boolean `false` is not a string. + /// assert!(!v["b"].is_string()); + /// # } + /// ``` + pub fn is_string(&self) -> bool { + self.as_str().is_some() + } + + /// If the `Value` is a String, returns the associated str. Returns None + /// otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert_eq!(v["a"].as_str(), Some("some string")); + /// + /// // The boolean `false` is not a string. + /// assert_eq!(v["b"].as_str(), None); + /// + /// // JSON values are printed in JSON representation, so strings are in quotes. + /// // + /// // The value is: "some string" + /// println!("The value is: {}", v["a"]); + /// + /// // Rust strings are printed without quotes. + /// // + /// // The value is: some string + /// println!("The value is: {}", v["a"].as_str().unwrap()); + /// # } + /// ``` + pub fn as_str(&self) -> Option<&str> { + match *self { + Value::String(ref s) => Some(s), + _ => None, + } + } + + /// Returns true if the `Value` is a Number. Returns false otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 1, "b": "2" }); + /// + /// assert!(v["a"].is_number()); + /// + /// // The string `"2"` is a string, not a number. + /// assert!(!v["b"].is_number()); + /// # } + /// ``` + pub fn is_number(&self) -> bool { + match *self { + Value::Number(_) => true, + _ => false, + } + } + + /// Returns true if the `Value` is an integer between `i64::MIN` and + /// `i64::MAX`. + /// + /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to + /// return the integer value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// # } + /// ``` + pub fn is_i64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_i64(), + _ => false, + } + } + + /// Returns true if the `Value` is an integer between zero and `u64::MAX`. + /// + /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// # } + /// ``` + pub fn is_u64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_u64(), + _ => false, + } + } + + /// Returns true if the `Value` is a number that can be represented by f64. + /// + /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// # } + /// ``` + pub fn is_f64(&self) -> bool { + match *self { + Value::Number(ref n) => n.is_f64(), + _ => false, + } + } + + /// If the `Value` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// # } + /// ``` + pub fn as_i64(&self) -> Option { + match *self { + Value::Number(ref n) => n.as_i64(), + _ => None, + } + } + + /// If the `Value` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// # } + /// ``` + pub fn as_u64(&self) -> Option { + match *self { + Value::Number(ref n) => n.as_u64(), + _ => None, + } + } + + /// If the `Value` is a number, represent it as f64 if possible. Returns + /// None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// # } + /// ``` + pub fn as_f64(&self) -> Option { + match *self { + Value::Number(ref n) => n.as_f64(), + _ => None, + } + } + + /// Returns true if the `Value` is a Boolean. Returns false otherwise. + /// + /// For any Value on which `is_boolean` returns true, `as_bool` is + /// guaranteed to return the boolean value. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert!(v["a"].is_boolean()); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert!(!v["b"].is_boolean()); + /// # } + /// ``` + pub fn is_boolean(&self) -> bool { + self.as_bool().is_some() + } + + /// If the `Value` is a Boolean, returns the associated bool. Returns None + /// otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert_eq!(v["a"].as_bool(), Some(false)); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert_eq!(v["b"].as_bool(), None); + /// # } + /// ``` + pub fn as_bool(&self) -> Option { + match *self { + Value::Bool(b) => Some(b), + _ => None, + } + } + + /// Returns true if the `Value` is a Null. Returns false otherwise. + /// + /// For any Value on which `is_null` returns true, `as_null` is guaranteed + /// to return `Some(())`. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": null, "b": false }); + /// + /// assert!(v["a"].is_null()); + /// + /// // The boolean `false` is not null. + /// assert!(!v["b"].is_null()); + /// # } + /// ``` + pub fn is_null(&self) -> bool { + self.as_null().is_some() + } + + /// If the `Value` is a Null, returns (). Returns None otherwise. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let v = json!({ "a": null, "b": false }); + /// + /// assert_eq!(v["a"].as_null(), Some(())); + /// + /// // The boolean `false` is not null. + /// assert_eq!(v["b"].as_null(), None); + /// # } + /// ``` + pub fn as_null(&self) -> Option<()> { + match *self { + Value::Null => Some(()), + _ => None, + } + } + + /// Looks up a value by a JSON Pointer. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Examples + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz")); + /// assert_eq!(data.pointer("/a/b/c"), None); + /// # } + /// ``` + pub fn pointer<'a>(&'a self, pointer: &str) -> Option<&'a Value> { + if pointer == "" { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + let tokens = pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")); + let mut target = self; + + for token in tokens { + let target_opt = match *target { + Value::Object(ref map) => map.get(&token), + Value::Array(ref list) => parse_index(&token).and_then(|x| list.get(x)), + _ => return None, + }; + if let Some(t) = target_opt { + target = t; + } else { + return None; + } + } + Some(target) + } + + /// Looks up a value by a JSON Pointer and returns a mutable reference to + /// that value. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Example of Use + /// + /// ```rust + /// extern crate serde_json; + /// + /// use serde_json::Value; + /// + /// fn main() { + /// let s = r#"{"x": 1.0, "y": 2.0}"#; + /// let mut value: Value = serde_json::from_str(s).unwrap(); + /// + /// // Check value using read-only pointer + /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); + /// // Change value with direct assignment + /// *value.pointer_mut("/x").unwrap() = 1.5.into(); + /// // Check that new value was written + /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); + /// + /// // "Steal" ownership of a value. Can replace with any valid Value. + /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); + /// assert_eq!(old_x, 1.5); + /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); + /// } + /// ``` + pub fn pointer_mut<'a>(&'a mut self, pointer: &str) -> Option<&'a mut Value> { + if pointer == "" { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + let tokens = pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")); + let mut target = self; + + for token in tokens { + // borrow checker gets confused about `target` being mutably borrowed too many times because of the loop + // this once-per-loop binding makes the scope clearer and circumvents the error + let target_once = target; + let target_opt = match *target_once { + Value::Object(ref mut map) => map.get_mut(&token), + Value::Array(ref mut list) => { + parse_index(&token).and_then(move |x| list.get_mut(x)) + } + _ => return None, + }; + if let Some(t) = target_opt { + target = t; + } else { + return None; + } + } + Some(target) + } + + /// Takes the value out of the `Value`, leaving a `Null` in its place. + /// + /// ```rust + /// # #[macro_use] + /// # extern crate serde_json; + /// # + /// # fn main() { + /// let mut v = json!({ "x": "y" }); + /// assert_eq!(v["x"].take(), json!("y")); + /// assert_eq!(v, json!({ "x": null })); + /// # } + /// ``` + pub fn take(&mut self) -> Value { + mem::replace(self, Value::Null) + } +} + +/// The default value is `Value::Null`. +/// +/// This is useful for handling omitted `Value` fields when deserializing. +/// +/// # Examples +/// +/// ```rust +/// # #[macro_use] +/// # extern crate serde_derive; +/// # +/// # extern crate serde_json; +/// # +/// use serde_json::Value; +/// +/// #[derive(Deserialize)] +/// struct Settings { +/// level: i32, +/// #[serde(default)] +/// extras: Value, +/// } +/// +/// # fn try_main() -> Result<(), serde_json::Error> { +/// let data = r#" { "level": 42 } "#; +/// let s: Settings = serde_json::from_str(data)?; +/// +/// assert_eq!(s.level, 42); +/// assert_eq!(s.extras, Value::Null); +/// # +/// # Ok(()) +/// # } +/// # +/// # fn main() { +/// # try_main().unwrap() +/// # } +/// ``` +impl Default for Value { + fn default() -> Value { + Value::Null + } +} + +mod de; +mod from; +mod index; +mod partial_eq; +mod ser; + +/// Convert a `T` into `serde_json::Value` which is an enum that can represent +/// any valid JSON data. +/// +/// ```rust +/// extern crate serde; +/// +/// #[macro_use] +/// extern crate serde_derive; +/// +/// #[macro_use] +/// extern crate serde_json; +/// +/// use std::error::Error; +/// +/// #[derive(Serialize)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn compare_json_values() -> Result<(), Box> { +/// let u = User { +/// fingerprint: "0xF9BA143B95FF6D82".to_owned(), +/// location: "Menlo Park, CA".to_owned(), +/// }; +/// +/// // The type of `expected` is `serde_json::Value` +/// let expected = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA", +/// }); +/// +/// let v = serde_json::to_value(u).unwrap(); +/// assert_eq!(v, expected); +/// +/// Ok(()) +/// } +/// # +/// # fn main() { +/// # compare_json_values().unwrap(); +/// # } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +/// +/// ```rust +/// extern crate serde_json; +/// +/// use std::collections::BTreeMap; +/// +/// fn main() { +/// // The keys in this map are vectors, not strings. +/// let mut map = BTreeMap::new(); +/// map.insert(vec![32, 64], "x86"); +/// +/// println!("{}", serde_json::to_value(map).unwrap_err()); +/// } +/// ``` +// Taking by value is more friendly to iterator adapters, option and result +// consumers, etc. See https://github.com/serde-rs/json/pull/149. +pub fn to_value(value: T) -> Result +where + T: Serialize, +{ + value.serialize(Serializer) +} + +/// Interpret a `serde_json::Value` as an instance of type `T`. +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +/// +/// ```rust +/// #[macro_use] +/// extern crate serde_json; +/// +/// #[macro_use] +/// extern crate serde_derive; +/// +/// extern crate serde; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `serde_json::Value` +/// let j = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); +/// +/// let u: User = serde_json::from_value(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +pub fn from_value(value: Value) -> Result +where + T: DeserializeOwned, +{ + T::deserialize(value) +} diff --git a/third_party/rust/serde_json/src/value/partial_eq.rs b/third_party/rust/serde_json/src/value/partial_eq.rs new file mode 100644 index 000000000000..ef67f5cb65f7 --- /dev/null +++ b/third_party/rust/serde_json/src/value/partial_eq.rs @@ -0,0 +1,102 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::Value; + +fn eq_i64(value: &Value, other: i64) -> bool { + value.as_i64().map_or(false, |i| i == other) +} + +fn eq_u64(value: &Value, other: u64) -> bool { + value.as_u64().map_or(false, |i| i == other) +} + +fn eq_f64(value: &Value, other: f64) -> bool { + value.as_f64().map_or(false, |i| i == other) +} + +fn eq_bool(value: &Value, other: bool) -> bool { + value.as_bool().map_or(false, |i| i == other) +} + +fn eq_str(value: &Value, other: &str) -> bool { + value.as_str().map_or(false, |i| i == other) +} + +impl PartialEq for Value { + fn eq(&self, other: &str) -> bool { + eq_str(self, other) + } +} + +impl<'a> PartialEq<&'a str> for Value { + fn eq(&self, other: &&str) -> bool { + eq_str(self, *other) + } +} + +impl PartialEq for str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self) + } +} + +impl<'a> PartialEq for &'a str { + fn eq(&self, other: &Value) -> bool { + eq_str(other, *self) + } +} + +impl PartialEq for Value { + fn eq(&self, other: &String) -> bool { + eq_str(self, other.as_str()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &Value) -> bool { + eq_str(other, self.as_str()) + } +} + +macro_rules! partialeq_numeric { + ($($eq:ident [$($ty:ty)*])*) => { + $($( + impl PartialEq<$ty> for Value { + fn eq(&self, other: &$ty) -> bool { + $eq(self, *other as _) + } + } + + impl PartialEq for $ty { + fn eq(&self, other: &Value) -> bool { + $eq(other, *self as _) + } + } + + impl<'a> PartialEq<$ty> for &'a Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + + impl<'a> PartialEq<$ty> for &'a mut Value { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + )*)* + } +} + +partialeq_numeric! { + eq_i64[i8 i16 i32 i64 isize] + eq_u64[u8 u16 u32 u64 usize] + eq_f64[f32 f64] + eq_bool[bool] +} diff --git a/third_party/rust/serde_json/src/value/ser.rs b/third_party/rust/serde_json/src/value/ser.rs new file mode 100644 index 000000000000..26595cc47607 --- /dev/null +++ b/third_party/rust/serde_json/src/value/ser.rs @@ -0,0 +1,827 @@ +// Copyright 2017 Serde Developers +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use serde::ser::Impossible; +use serde::{self, Serialize}; + +use error::{Error, ErrorCode}; +use map::Map; +use number::Number; +use value::{to_value, Value}; + +#[cfg(feature = "arbitrary_precision")] +use serde::ser; + +#[cfg(feature = "arbitrary_precision")] +use number::{SERDE_STRUCT_FIELD_NAME, SERDE_STRUCT_NAME}; + +impl Serialize for Value { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: ::serde::Serializer, + { + match *self { + Value::Null => serializer.serialize_unit(), + Value::Bool(b) => serializer.serialize_bool(b), + Value::Number(ref n) => n.serialize(serializer), + Value::String(ref s) => serializer.serialize_str(s), + Value::Array(ref v) => v.serialize(serializer), + Value::Object(ref m) => { + use serde::ser::SerializeMap; + let mut map = try!(serializer.serialize_map(Some(m.len()))); + for (k, v) in m { + try!(map.serialize_key(k)); + try!(map.serialize_value(v)); + } + map.end() + } + } + } +} + +pub struct Serializer; + +impl serde::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result { + self.serialize_i64(value as i64) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + #[inline] + fn serialize_f32(self, value: f32) -> Result { + self.serialize_f64(value as f64) + } + + #[inline] + fn serialize_f64(self, value: f64) -> Result { + Ok(Number::from_f64(value).map_or(Value::Null, Value::Number)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + let mut s = String::new(); + s.push(value); + self.serialize_str(&s) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + let vec = value.iter().map(|&b| Value::Number(b.into())).collect(); + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + let mut values = Map::new(); + values.insert(String::from(variant), try!(to_value(&value))); + Ok(Value::Object(values)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option) -> Result { + Ok(SerializeMap::Map { + map: Map::new(), + next_key: None, + }) + } + + #[cfg(not(feature = "arbitrary_precision"))] + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_map(Some(len)) + } + + #[cfg(feature = "arbitrary_precision")] + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { + if name == SERDE_STRUCT_NAME { + Ok(SerializeMap::Number { out_value: None }) + } else { + self.serialize_map(Some(len)) + } + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Map::new(), + }) + } +} + +pub struct SerializeVec { + vec: Vec, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec, +} + +pub enum SerializeMap { + Map { + map: Map, + next_key: Option, + }, + #[cfg(feature = "arbitrary_precision")] + Number { out_value: Option }, +} + +pub struct SerializeStructVariant { + name: String, + map: Map, +} + +impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + self.vec.push(try!(to_value(&value))); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } +} + +impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + self.vec.push(try!(to_value(&value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Array(self.vec)); + + Ok(Value::Object(object)) + } +} + +impl serde::ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where + T: Serialize, + { + match *self { + SerializeMap::Map { + ref mut next_key, .. + } => { + *next_key = Some(try!(key.serialize(MapKeySerializer))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + } + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where + T: Serialize, + { + match *self { + SerializeMap::Map { + ref mut map, + ref mut next_key, + } => { + let key = next_key.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = key.expect("serialize_value called before serialize_key"); + map.insert(key, try!(to_value(&value))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { map, .. } => Ok(Value::Object(map)), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer; + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T, + ) -> Result + where + T: Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, _value: bool) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(value.to_string()) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(value.to_string()) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(value.to_string()) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(value.to_string()) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(value.to_string()) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(value.to_string()) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(value.to_string()) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(value.to_string()) + } + + fn serialize_f32(self, _value: f32) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_f64(self, _value: f64) -> Result { + Err(key_must_be_a_string()) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { + match *self { + SerializeMap::Map { .. } => { + try!(serde::ser::SerializeMap::serialize_key(self, key)); + serde::ser::SerializeMap::serialize_value(self, value) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { ref mut out_value } => { + if key == SERDE_STRUCT_FIELD_NAME { + *out_value = Some(value.serialize(NumberValueEmitter)?); + Ok(()) + } else { + Err(invalid_number()) + } + } + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value, .. } => { + Ok(out_value.expect("number value was not emitted")) + } + } + } +} + +impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: Serialize, + { + self.map.insert(String::from(key), try!(to_value(&value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Object(self.map)); + + Ok(Value::Object(object)) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberValueEmitter; + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "arbitrary_precision")] +impl ser::Serializer for NumberValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_number()) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_number()) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result { + let n = try!(value.to_owned().parse()); + Ok(Value::Number(n)) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result { + Err(invalid_number()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + _value: &T, + ) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } +}